How do I load an image to an apk in delphi XE8 - android

I am working on an app in Delphi XE8.
When I run the program on my phone, it gives me an error:
Loading bitmap failed(image.png)
My code works as follows:
if ListBox1.ItemIndex = 0 then
begin
img.bitmap.LoadFromFile('Image.png');
iMin:= Round(iNumber * 1);
iMax:= Round(iNumber *13.24);
iAvg:= Round(iNumber * 2.59);
label7.Text:= inttostr(iMin);
label5.Text:= inttostr(iAvg);
label6.Text:= inttostr(iMax);
label2.Text:= 'Minimum';
label3.Text:= 'Average';
label4.Text:= 'Maximum';
end
else
...
Please note the image is saved in the same folder as my program.

Don't use relative paths. Always use absolute paths.
You need to use the Deployment Manager to deploy the image file to an appropriate folder on the phone, and then use the System.IOUtils.TPath class to locate that folder at runtime:
Standard RTL Path Functions across the Supported Target Platforms
On Android, deploy the image file to the ./assets/internal folder, and then use the TPath.GetDocumentsPath() method at runtime, as documented on this blog:
Deploying and accessing local files on iOS and Android
What the EDN documentation and blog both fail to mention is that you also need to add the System.StartupCopy unit to your app's uses clause.
uses
..., System.IOUtils, System.StartupCopy;
...
img.bitmap.LoadFromFile(TPath.Combine(TPath.GetDocumentsPath, 'Image.png'));

Related

Load a set of images from a directory in React Native

I have a group of images in a directory and I want to add the paths to an array in react native.
The image names are 1.png, 2.png, 3.png... 20.png
The following is the method I currently use
const images = [require('../assets/1/1.png'),
require('../assets/1/2.png'),
require('../assets/1/3.png'),
...
require('../assets/1/20.png'),];
This is possible when there is a limited number of images. In some cases I might have to add 300 images. So is there an easy way to do this?
I tried adding in a loop but it does not work.
for (let i = 1; i < 300; i++) {
images.push(require('../assets/1/'+i+'.png'))
}
EDIT :
The following error occurs in the above approach,
error: bundling failed: Error: Components\IdleLoop.js:Invalid call at line 9: require('../assets/1/' + i + '.png')
at F:\_work\sampleApp\node_modules\metro\src\JSTransformer\worker.js:317:19
at Generator.next (<anonymous>)
at asyncGeneratorStep (F:\_work\sampleApp\node_modules\metro\src\JSTransformer\worker.js:75:24)
at _next (F:\_work\sampleApp\node_modules\metro\src\JSTransformer\worker.js:95:9)
As far as I know because React Native applications are statically bundled on build time, required assets are linked in advanced therefore there isn't a way to load them dynamically on runtime. I've ran into the same problem and gave up on that and ended up linking everything manually/statically.
For more information you might want to check out React Native - Image Require Module using Dynamic Names, which concludes the same.

How to read tensorflow memory mapped graph file in android?

Using Tensorflow 1.0.1 it's fine to read optimized graph and quantized graph in android using TensorFlowImageClassifier.create method, such as:
classifier = TensorFlowImageClassifier.create(
c.getAssets(),
MODEL_FILE,
LABEL_FILE,
IMAGE_SIZE,
IMAGE_MEAN,
IMAGE_STD,
INPUT_NAME,
OUTPUT_NAME);
But according to the Peter Warden's Blog(https://petewarden.com/2016/09/27/tensorflow-for-mobile-poets/), it's recommended to use memory mapped graph in mobile to avoid memory related crashes.
I built memmapped graph using
bazel-bin/tensorflow/contrib/util/convert_graphdef_memmapped_format \
--in_graph=/tf_files/rounded_graph.pb \
--out_graph=/tf_files/mmapped_graph.pb
and it created fine, but when I tried to load the file with TensorFlowImageClassifier.create(...) it says the file is not valid graph file.
In iOS, it's ok to load the file with
LoadMemoryMappedModel(
model_file_name, model_file_type, &tf_session, &tf_memmapped_env);
for it has a method for read memory mapped graph.
So, I guess there's a similar function in android, but I couldn't find it.
Could someone guide me how to load memory mapped graph in android ?
Since the file from the memmapped tool is no longer a standard GraphDef protobuf, you need to make some changes to the loading code. You can see an example of this in the iOS Camera demo app, the LoadMemoryMappedModel() function:
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/ios_examples/camera/tensorflow_utils.mm#L159
The same code (with the Objective C calls for getting the filenames substituted) can be used on other platforms too. Because we’re using memory mapping, we need to start by creating a special TensorFlow environment object that’s set up with the file we’ll be using:
std::unique_ptr<tensorflow::MemmappedEnv> memmapped_env;
memmapped_env->reset(
new tensorflow::MemmappedEnv(tensorflow::Env::Default()));
tensorflow::Status mmap_status =
(memmapped_env->get())->InitializeFromFile(file_path);
You then need to pass in this environment to subsequent calls, like this one for loading the graph.
tensorflow::GraphDef tensorflow_graph;
tensorflow::Status load_graph_status = ReadBinaryProto(
memmapped_env->get(),
tensorflow::MemmappedFileSystem::kMemmappedPackageDefaultGraphDef,
&tensorflow_graph);
You also need to create the session with a pointer to the environment you’ve created:
tensorflow::SessionOptions options;
options.config.mutable_graph_options()
->mutable_optimizer_options()
->set_opt_level(::tensorflow::OptimizerOptions::L0);
options.env = memmapped_env->get();
tensorflow::Session* session_pointer = nullptr;
tensorflow::Status session_status =
tensorflow::NewSession(options, &session_pointer);
One thing to notice here is that we’re also disabling automatic optimizations, since in some cases these will fold constant sub-trees, and so create copies of tensor values that we don’t want and use up more RAM. This setup also means it's hard to use a model stored as an APK asset in Android, since those are compressed and don't have normal filenames. Instead you'll need to copy your file out of an APK onto a normal filesytem location.
Once you’ve gone through these steps, you can use the session and graph as normal, and you should see a reduction in loading time and memory usage.

How can I use `asset://` for non-APK file(s) on Android in a mapbox-gl Style?

I've been using Mapbox GL Native (specifically react-native-mapbox-gl). I'm generating my own vector tiles on a server, and I'd like to have the user download them onto their device from the mobile app. Then I want Mapbox GL to use the local tiles, specified via a TileJSON file referenced in the Mapbox GL Style file.
I've got it working on iOS (at least in the simulator). My style.json looks like the following:
{
"version":8,
"name":"Bright",
"sources":{
"mapbox":{
"type":"vector",
"url": "asset:///absolute/path/map/tile.json"
}
},
"sprite":"asset:///absolute/path/map/sprites/mysprite",
"glyphs":"asset:///absolute/path/map/glyphs/{fontstack}/{range}.pbf",
"metadata":{...},
"layers":[...]
}
with the tile.json looking like:
{
"tiles":[
"asset:///absolute/path/map/tiles/{z}/{x}/{y}.pbf"
],
"tilejson":"2.0.0",
// plus lots of other stuff
}
On Android this doesn't work. It appears that asset:// only works on files bundled inside the APK, not on the filesystem.
Is there something I can do on the Android platform to let Mapbox GL load my downloaded tiles from off the device?
Have you tried using the file:/// path? This usually loads from your app's file directory, eg.
"file:///absolute/path/map/tiles/{z}/{x}/{y}.pbf"

Show image in TImage dynamically (at run time) without opendialog in c++ builder xe8

I want to show image (png,jpg etc) in dynamically created (as per requirement and fully through coding) TImage component, at runtime in C++ builder xe8 (not delphi). But I dont want to use opendialogbox (suggested in many web sites). I want to run this app on my android device. I tried to use LoadFromFile(), it crashes the app on android, but when I run this on windows, its running smoothly. I am just a beginner to c++ builder. So guys pls help. Thanx in advance for any kind of help.Here is what I did.
void __fastcall TForm1::TForm1(TComponent* Owner)
{
TImage* img = new TImage(this);
img->Parent = this;
img->Bitmap->LoadFromFile("D:\\res\\profile.png");
}
Did you see what is the error?
If you run the program with the provided by you code I assume the error would be that the file is not found, because there is no such directory "D:\" in android.
One way to set the path is to write a static path which points to your image. For example : "/storage/sdcard0/DCIM/Camera/MyImage.jpg";
The second way is to include the <System.IOUtils.hpp> header and to use some built-in functions like:
System::Ioutils::TPath::GetPicturesPath();
System::Ioutils::TPath::GetAlarmsPath();
You can check them out, they might be useful.

locales/en-US/translation.json loads in Eclipse but fail in iphone

I am currently developing a cross platform mobile app using phonegap 2.5. When app starts it loads a json file for setting the app's language. It works perfectly in android but in ios it gets me that error: failed loading: locales/el-GR/translation.json. I tried to change the relative path for locales folder or move the current folder to other scope but neither seems to work.
WWW subfolder path
_www/
__index.html
__js/
___some js files like as main.js, cordova.js,jqmobi.min.js, i18next-1.7.1.min.js e.t.c.
__locales/
___en-US/
____translation.json
And the function i call in main.js:
i18n.init(
{
lng: AppSettings.Language.get(),
fallbackLng: 'en-US',
/* Where __lng__/__ns__.json = en-US/translation.json */
resGetPath : '/locales/__lng__/__ns__.json',
resPostPath: '/locales/__lng__/__ns__.json',
debug: true
},
function(){
}
);
In main.js i give the relative url path for loading translation.json (locales/en-US/translation.json). This works fine in android but in ios it doesn't seem to load it.
So, if you can, i could need some help.
Does iphone understand differently the relative paths of a phonegap mobile app?
What path should i give so that the app loads the translation.json?
If you need more info tell me.
Ty in advance.

Categories

Resources