Reading JPG into BitmapData in ActionScript 3 (JPG is inside APK file) - image

I'm using Adobe AIR to make APK file for my Android phone. Inside the APK package there is a SWF file and in the same folder as the SWF file there is a subfolder named "images", which contains image.jpg.
I'm trying to read that image.jpg into the program at runtime but can't get the location of it (the program doesn't seem to find it.
Here's what I'm trying:
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
loader.load(new URLRequest("images/image.jpg"));
while (bitmapData==null) {} //wait until loaded
return bitmapData;
The onComplete-function puts sets the bitmapData field. However, the COMPLETE event never happens so the while loop never exists.
I have also tried:
loader.load(new URLRequest("/images/image.jpg"));
loader.load(new URLRequest("app:/images/image.jpg"));
loader.load(new URLRequest("app-storage:/images/image.jpg"));
loader.load(new URLRequest("file:/images/image.jpg"));
None of it works.
I can't get this to work even when trying without the APK file, when only running the SWF file that is generated (the images subfolder is in the same folder as the SWF file).
I can't embed the JPG into the SWF file itself because I need to have a lot of image files and Flash CS6 runs out of memory when making such a big SWF file (reading the images externally would also mean a whole lot less compilation time).
Any ideas? How can I get put the external JPG file into BitmapData? Remember that the image is not outside of the APK file, it is packaged inside it.
Note: I'll also export the thing into a iOS ipa package later so it have to work there as well.
Edit because I can't self-answer due to my reputation.
Strille made me realize that the ActionScript Virtual Machine is single-threaded.
So it's impossible to make a thread sleep (wait) for an image being loaded. Instead I have to sigh rewrite a lot of code so that things are halted and continues when the onComplete function is called.
This thing that I tried before actually works but couldn't complete due to the while loop:
loader.load(new URLRequest("app:/images/image.jpg"));

If I remember correctly, you should be able to do it like this:
loader.load(new URLRequest(new File("app:/images/image.jpg").url));
Since we're using the File class, the above will not run in the Flash Player, just on iOS or Android.

From my experience there are two practical methods to load assets from a running Android APP using AIR
using URLLoader and .url property of the File instance
using FileStream (which receives a File instance)
Adding to project
You can package the files inside the APK using
the same technique as packaging ICONS, inside the .xml descriptor file for your app.
And make sure you add those to your IDE in the Android section (applies to IntelliJ and Flash Builder) "Files and folders to package"
- add the path to your wanted assets folder, and give it a relative name alias.
Elaboration
The assets themselves are placed (when the APP is installed),
inside the ''applicationDirectory'' which is available for AIR,
Yet since newer Android OS's, and Flash player security issues,
it is not possible to access those assets via the nativePath,
only the 'url' property of the File instance.
Best Practice
Use URLLoader and .url property of the File instance,
as it is also Asynchronous by nature and can resolve PNG / JPG files
using native decoder instead of having to do this manually
reading a FileStream (which returns a a ByteArray)
var f:File = File.applicationDirectory.resolvePath('images/myimage.png');
loader.load(new URLRequest(f.url));
and,
If I'm missing more ways, please let know... )

Related

I cant load HTML file into WebView from app specific storage since Android 11 (SDK30)

My App has the following use case:
We download a geojson file, a html file and some audio files from a server for a specific language a user has chosen and we are saving this in the app specific file directory.
The directory path is the following for each use case:
For the HTML file we have:
/storage/emulated/0/Android/data/my.example.com/files/ExampleApp/EnginePayload/de/html-file.html
For the json file we have:
/storage/emulated/0/Android/data/my.example.com/files/ExampleApp/LocationPayload/de/geojson-file.geojson
Audiodata:
/storage/emulated/0/Android/data/my.example.com/files/ExampleApp/Audio/de/intro.mp3
/storage/emulated/0/Android/data/my.example.com/files/ExampleApp/Audio/de/outro.mp3
and so on...
Since i have to change the minSDK and compileSDK to 30 i don't get the files to work.
I load the html-file.getAbsolutePath() to the webView but the webview client does not call ANY callback!
The audio files will not be started, because we use javascript functions to do that.
As i unterstand it, the app specific directory does not have to be changed because even on Android 11, the app has permission to read and write its own created files.
The moment i change it back to SDK 29, everything is working.
I don't know what to do. Can someone help me please?
I fixed it myself after hours!
My assumptions were right. The app had access to the files, because the app created them itself. so there was not an issue here to read the files...
Here is my fix and i hope it will help someone in the future:
There was something missing in the settings for the WebView.
webView.getSettings().setAllowFileAccess(true);
This allows me now to load a html file (with absolute Path) from the app specific directory for Android 11.
Here is my code:
webView.getSettings().setAllowFileAccess(true);
File extDir = cxt.getExternalFilesDir(null);
//htmlPath is something like this: "ExampleApp/EnginePayload/de/html-file.html"
File twine = new File(extDir.toString() + "/" + htmlPath);
webView.loadUrl(twine.getAbsolutePath());

Image inside folder with two-letter name ('bg') disappears when packaged as UWP app

I've got a really weird problem building a Windows 10 UWP app. When I test on my device in both debug and release modes, an image I set as Background appears perfectly fine. It resizes, etc.
However, when I package the app in preparation for store deployment and install the package to test, images are showing as white.
Here's the code in question:
mainGrid.Background = new ImageBrush { ImageSource = new BitmapImage(new Uri(#"ms-appx:///Assets/bg/" + Config.bgImage + ".jpg")), Stretch = Stretch.UniformToFill };
What confuses me the most is why it works in debug/release, but only fails when its released as a package.
The image is set as "Content" and "Copy Always".
Any ideas?
Thanks in advance!
Per comment, this is due to a folder being named bg and the project being set to create a "bundle" (ie, a main package and then a separate package for each language).
For better or worse, the packaging system assumes that any directory with a 2-letter name is a language code (like "en" or "de") and therefore assumes the assets are specific to that language. Those assets are placed in a separate package that are only installed if applicable for the current user.
If you have a large number of assets, and you're localizing them, using a bundle is still a good approach to minimize the app size and download time, in which case you would need to change the directory name to something a bit longer (technically you can control the packaging yourself but it's a lot of work... renaming is probably easier).
But if you don't localize / aren't worried about bloating the app too much, then creating a single package is fine.

Cocoa Mac OS X application bundling 1000 images

We have a Cocoa Mac OS X application in which we want to bundle around 500 images. Each image is around 10kb so size isn't a problem.
These images are not exactly resources in the app, they are sample images.
Basically, we have simple button that would let the user copy these images to a directory.
The solution also needs to be "dump in, dump out" -- so we don't want to store individual image file names somewhere in our application; we just want to have a directory of images that can be copied.
How do I package these into my application?
The question turns into: How do I make a directory resource containing the images.
In our case everything gets flattened into the MyApp.app/Contents/Resources and this approach would require us to put image names in the app so that we can copy those.
Put the images into a folder. Drag the folder into your project in Xcode. In the resulting dialog, make sure you copy, make sure you create a folder reference, and make sure you add to your app target. Done. Now the folder is part of your app bundle and you can refer to it from your code without knowing anything about its contents.
The folder /Library/Application Support is for support files that, if deleted, would not affect the execution of an application. I would suggest this is ideal for your product's sample images.
As Apple's documentation states for Application Support:
Use this directory to store all app data files except those associated with the user’s documents. For example, you might use this directory to store app-created data files, configuration files, templates, or other fixed or modifiable resources that are managed by the app. An app might use this directory to store a modifiable copy of resources contained initially in the app’s bundle.
So, use pkgbuild / productbuild to install them to /Library/Application Support/<ProductName>/
Because size is not an issue, you can just put all your sample images in separate Asset Catalog file.

How to load images (jpg) in QML generated at runtime

my question is quite simple.
I have a Qt application with a Gui developed with QML.
My back-end side generates and saves jpg images in a folder called /images .
I am able to send from C++ to QML the strings holding the name of the images that I want to show. Sadly my QML Image object doesn't display anything.
It seems that if an image can be displayed only if it has been previously declared in the qml.qrc file.
Sadly, again, qrc files do not support wildcards yet!
https://bugreports.qt.io/browse/QTBUG-1400
Is there a workaround?
The name of the images are not fixed, they are generated with certain runtime values i.e. timestamp.
Thank you
By default it will search the image source in the qrc file. To make it go to the actual file system, prepend a file:/// to the path.

Can't access files in my Mac APP Bundle

I am using wxwidget on my Mac OSX and just cant make my app access my resources directoy within my app bundle.
I have a file name image.bmp in my resources folder and accessing it through :
m_bitmap1 = new wxStaticBitmap( this, wxID_ANY, wxBitmap( wxT("Resources/image.bmp"), wxBITMAP_TYPE_ANY ), wxDefaultPosition, wxDefaultSize, 0 );
my app yell : "File not found error" on that file. I also tried ./Resource, or just image.bmp but nothing seems to work.
Looking into the app file I can see the file in there. but for some strange reason it seems to ignore it.
Any idea ?
By default wxOSX will only load PNG and JPEG bitmaps from the resources, so I advise you to convert your bitmap to PNG and use wxBITMAP_TYPE_PNG_RESOURCE in the ctor. You also need to remove the explicit "Resources/" as the path is looked up under this directory of your bundle automatically. I.e. the recommended solution is to use wxBitmap("image.png", wxBITMAP_TYPE_PNG_RESOURCE).
Notice that this works under Windows too, provided you embed your PNG into the resources using RCDATA type as explained in wxBITMAP_PNG() documentation. For the other platforms you would need to embed it directly into the program code, this is also explained in the same link.
Otherwise, i.e. if you really want to use BMP, you need to use wxStandardPaths::GetResourcesDir() to construct the full path to your bitmap explicitly.

Resources