Cannot read image file in appcelerator titanium - titanium

I have an image stored at /assets in my project folder and I am trying to read it using Ti.Filesystem.getFile(). The code prints the blob data in android but it prints undefined in iOS.
Following function is called on Button click event https://pastebin.com/QgqLQPyz
function readImg(e) {
var localPath = '/butterfly.jpg';
var cachedFilename = Ti.Utils.sha1(localPath) + localPath.substr(localPath.lastIndexOf('.'));
console.log("cachedFilename:---"+cachedFilename);
var cachedFile = Ti.Filesystem.getFile(Ti.Filesystem.applicationCacheDirectory, cachedFilename);
if(!cachedFile.exists()){
var blob = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory, localPath).read();
console.log("-----------blob in not exists:"+JSON.stringify(blob));
}
}
When the same image path is set in ImageView it gets displayed so the issue is not with path . What am I missing here ? pls help. Thank you.

The best option so you don't have to do anything specific to the images at all (keep in mind, image manipulation is pretty heavy to do on runtime), is to use a module that was made for this purpose, av.imageview. This allows you to configure all kinds of content modes.
An option to get your code to work is to get the blob using the the getAsset method.
var blob = Ti.Filesystem.getAsset('/images/butterfly.jpg');
and then resize where you see fit. But I would advise you, if you do need to do this every time the app runs, then just resize once and store that resized image to be used after that. That way there will only be a single time the image needs resizing.

Related

Cannot find the exact eror sometimes showing Adapter not attached sometimes cannot find memetrack [duplicate]

I'm running Ubuntu 16.04. And on Android Studio when I try to run my application in the emulator I get the following error:
FATAL EXCEPTION: main
Process: project name here, PID: 2528
java.lang.RuntimeException: Canvas: trying to draw too large(216090000bytes) bitmap.
at android.view.DisplayListCanvas.throwIfCannotDraw(DisplayListCanvas.java:260)
at android.graphics.Canvas.drawBitmap(Canvas.java:1415)
at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:528)
at android.widget.ImageView.onDraw(ImageView.java:1316)
at android.view.View.draw(View.java:17185)
at android.view.View.updateDisplayListIfDirty(View.java:16167)
at android.view.View.draw(View.java:16951)
at android.view.ViewGroup.drawChild(ViewGroup.java:3727)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3513)
at android.view.View.updateDisplayListIfDirty(View.java:16162)
at android.view.View.draw(View.java:16951)
at android.view.ViewGroup.drawChild(ViewGroup.java:3727)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3513) at
etc...
I did have to run through some hoops to get my emulator working however, needed to create a sym-link so I can run the emulator on AMD. Not sure if this is part of the problem. And for the life of me I cannot figure why it continues to do this. In my group there are others who emulate the project just fine on the same emulated phone and SDK.
Move your image in the (hi-res) drawable to drawable-xxhdpi. But in app development, you do not need to use large image. It will increase your APK file size.
The solution is to move the image from drawable/ folder to drawable-xxhdpi/ folder, as also others have mentioned.
But it is important to also understand why this somewhat weird suggestion actually helps:
The reason is that the drawable/ folder exists from early versions of android and is equivalent to drawable-mdpi. When an image that is only in drawable/ folder is used on xxhdpi device, the potentially already big image is upscaled by a factor of 3, which can then in some cases cause the image's memory footprint to explode.
This solution worked for me.
Add these lines in your Manifest application tag
android:largeHeap="true"
android:hardwareAccelerated="false"
I had the same problem.
If you try to upload an image that is too large on some low resolution devices, the app will collapse.
You can make several images of different sizes (hdpi, xxdpi and more) or simply use an external library to load images that solve the problem quickly and efficiently.
I used Glide library (you can use another library like Picasso).
panel_IMG_back = (ImageView) findViewById(R.id.panel_IMG_back);
Glide
.with(this)
.load(MyViewUtils.getImage(R.drawable.wallpaper)
.into(panel_IMG_back);
This issue can be resolved by 3 methods as follows:
Method 1:
By adding image into a res/drawable-nodpi folder (By doing this it will not pre-scale your image).
Method 2:
Generate all dpi(hdpi,ldpi,mdpi,xhdpi,xxhdpi,xxxhdpi) of image and add to drawable folder. (This process will increase APK size).
Method 3:
Add image to drawable/drawable-xxhdpi folder.
All these methods are verified.
Turns out the problem was the main image that we used on our app at the time. The actual size of the image was too large, so we compressed it. Then it worked like a charm, no loss in quality and the app ran fine on the emulator.
For this error was like others said a big image(1800px X 900px) which was in drawable directory, I edited the image and reduced the size proportionally using photoshop and it worked...!!
If you don't want your image to be pre-scaled you can move it to the res/drawable-nodpi/ folder.
More info: https://developer.android.com/training/multiscreen/screendensities#DensityConsiderations
if you use Picasso change to Glide like this.
Remove picasso
Picasso.get().load(Uri.parse("url")).into(imageView)
Change Glide
Glide.with(context).load("url").into(imageView)
More efficient Glide than Picasso draw to large bitmap
I also had this issue when i was trying to add a splash screen to the android app through the launch_backgrgound.xml . the issue was the resolution. it was too high so the images memory footprint exploded and caused the app to crash hence the reason for this error. so just resize your image using a site called nativescript image builder so i got the ldpi,mdpi and all the rest and it worked fine for me.
I just created directory drawable-xhdpi(You can change it according to your need) and copy pasted all the images to that directory.
This can be an issue with Glide. Use this while you are trying to load to many images and some of them are very large:
Glide.load("your image path")
.transform(
new MultiTransformation<>(
new CenterCrop(),
new RoundedCorners(
holder.imgCompanyLogo.getResources()
.getDimensionPixelSize(R.dimen._2sdp)
)
)
)
.error(R.drawable.ic_nfs_default)
.into(holder.imgCompanyLogo);
}
Try using an xml or a vector asset instead of a jpg or png.
The reason is quite obvious in the exception name itself i.e. the resolution of the resource is too large to render.
You can png to xml using online tools like https://svg2vector.com/ OR add your image to drawable-xxhdpi folder.
Solution for Picasso is add Transformation for resize image.
class ResizeTransformation(private val maxSize: Int) : Transformation {
override fun transform(source: Bitmap?): Bitmap? {
var result:Bitmap? = null
if (source != null) {
var width = source.width
var height = source.height
val bitmapRatio = width.toFloat() / height.toFloat()
if (bitmapRatio > 1) {
width = maxSize;
height = (width / bitmapRatio).toInt()
} else {
height = maxSize;
width = (height * bitmapRatio).toInt()
}
result = Bitmap.createScaledBitmap(source, width, height, true)
source.recycle()
}
return result
}
override fun key() = "resize()"
}
Use:
Picasso.get()
.load(url)
.transform(ResizeTransformation(2400)) //FHD+ resolution
.into(view)
Convert your all png formats into webs format. You can do it by Android Studio.

Force Image control to re-download the image

I have an Image control on Page1.xaml that is pointing at a URL: http://www.example.com/blah.jpg
I navigate to Page2.xaml and upload a new image to that url using my WebAPI. I call Frame.GoBack() to navigate back to Page1.xaml.
The old image is still displayed in the Image control. How can I make sure that Image control re-downloads the image even though its at the same URL?
The only way I found was to append a query string to the end of the image. It's a bit of a hack and it can interfere with Save operations but it is effective.
Just to be clear, I set the property with the image url with a value like this:
"http://www.example.com/blah.jpg?id=" + Guid.NewGuid()
That triggers the RaisePropertyChanged event and the Image control is tricked into thinking the image changed.
Set the BitmapImage.CreateOptions property to IgnoreImageCache.
From MSDN:
The other possible value for CreateOptions is
BitmapCreateOptions.IgnoreImageCache. You should only use
BitmapCreateOptions.IgnoreImageCache in cases where you know that the
source image file as retrieved by URI has the potential to change over
time. Otherwise, setting CreateOptions to use
BitmapCreateOptions.IgnoreImageCache causes all newly retrieved image
sources to be decoded again, which can negatively impact performance.
...

Databinding uri source of imagebrush

In my application i am binding several properties to a custom user control, and everything works fine, except the images are not showing. For binding i have used the following codes:
Categories.Add(new Models.Category { Name = "Pizza", Count= 4, ImageUri = new Uri("Images/pizza.png", UriKind.Relative) });
I have also tried with different urikinds but the images are never showing.
what could go wrong? The images are in my solutions Images folder.
Use the ms-appx URI scheme:
ImageUri = new Uri("ms-appx:///Images/pizza.png");
Take care to really write ///.
Also make sure that the Build Action of the image file is set to Content, as pointed out in the other answer. Setting Copy to Output Directory does however not seem to be necessary.
Be sure you set the properties of the image so that it is available during runtime. Sometimes if employing Design Time data in Blend, you will see the images in Design Time, but then nothing during run time. The reason is that the images were never deployed with the rest of the solution. Be sure the Build Action on each image is set to Content and I usually set the Copy to Output Directory to Copy if Newer.

WinJS css file from local storage

Follow up to this question:
apply downloaded CSS on windows 8 metroUI app
So, yes, Windows says "for security reasons, you cannot navigate to HTML you have downloaded to this location and you cannot run any executable or potentially executable code, such as script or CSS. It is intended for media such as images or videos and the like."
But I really, really want to use that css file from my local storage. Shouldn't I be able to use the execUnsafeLocalFunction method to bypass this restriction like this?:
MSApp.execUnsafeLocalFunction(function () {
el["href"] = "ms-appdata:///local/style.css"
});
It still throws "An app can’t load remote web content in the local context."
I also tried just reading the file with localFolder.getFileAsync and readText, but nothing seems to help. Is there really no way to work around this?
I think I found a way to get the CSS to load.
I tested the code below by adding a css file that sets the body background to red in the local storage folder.
The code reads the contents of the file, creates a style tag in the head and adds the content of the css file to the style.
var url = new Windows.Foundation.Uri(filename);
Windows.Storage.StorageFile.getFileFromApplicationUriAsync(url).then(function (file) {
Windows.Storage.FileIO.readTextAsync(file).then(function(text) {
var style = document.createElement("style");
style.innerText = text;
document.getElementsByTagName("head")[0].appendChild(style);
});
});

Capture and save a photo in XAML/C# for a Windows store application

I'm trying to take and save a photo using a windows surface device.
I'm using the code below to take a photo and this work but I'd like to automatically create a directory on the device's local drive and save this photo there without any dialog prompts.
So the code I use to capture to photo is as follows:
CameraCaptureUI camera = new CameraCaptureUI();
StorageFile file = await camera.CaptureFileAsync(CameraCaptureUIMode.Photo);
if (file!=null)
{
using (IRandomAccessStream ras=await file.OpenAsync(FileAccessMode.Read))
{
BitmapImage source = new BitmapImage();
source.SetSource(ras);
imageBuildingPhoto.Source = source; // this is just an image control.
}
}
So after this I'd like to automatically save the photo to a new directory. e.g.
My Pictures\NewDirectory\Photo1.jpg
Anybody got any idea how I can do this?
This is a windows store application written using C#4.5 and XAML.
Thanks in advance
Use the CopyAsync method on the StorageFile object you get back (file). You can specify a directory and file name. If you need to create your own directory structure, you will need to enable access to the appropriate library in the Package Manifest then create it in code. You will then use the StorageFolder class and its CreateFolderAsync method to create folders.
http://aka.ms/30Days has some great resources for learning about scenarios like this. Might be worth checking out.
Your code will need to look to see if that folder exists and create it if it does not. Your app will need to declare the capability to access the user's Photos library in the app manifest, too.
To take a picture, your code is correct. I have a walkthrough in case you want to verify it against some other code: http://blog.jerrynixon.com/2012/10/walkthrough-capturing-photos-in-your.html
To interact with the file system, this can be tricky, but I have a longer write up on that if you want to reference it: http://blog.jerrynixon.com/2012/06/windows-8-how-to-read-files-in-winrt.html
The answer to your question is, yes you can. I have done it in my own apps. Now, it's just a matter of you implementing it in yours. You will find it to be pretty easy.