I've been having problems with large images being resized for UI use in Android.
Look at this image, it's an ImageView:
The original image (That arc is a progressbar) is around 10 times bigger than what you see here. In UWP (Windows Platform) we had no problem using a very large image, but here in Android, I beleive it's the Nearest Neighbour method used for fitting images into UI elements, which as you see, causes sharp edges.
Is there any way to switch it into another method? Like Bicubic? It happens in all Android versions I've tested (4.1, 5.0, 6.0).
Just to mention, I'm using Xamarin 4, which I don't beleive as a contributing factor here.
No luck searching through the internet, I'm afraid I'm the only one having this problem.
Thanks.
As mentioned above, you should prefer to use vector image instead of pixel image.
But if you have to use pixel image, maybe you could use BitmapRegionDecoder to decode lines of image and write your own resample algorithm(like Bilinear Interpolation, it's much better than the Near Neighbor) to resize the image, typically in JNI side.
Another possible way is to use "filter" parameter while calling Bitmap.createBitmap method as your original image would not cause OOM issue, just set it to true, it works to reduce the artifacts.
You should use Vector Images instead of Bitmap Images.
Bitmap x Vector
A bitmap represents an image by a series of colored pixels. Whereas a vector image is represented by geometric shapes (lines, curves) using colors.
The main utility of a vector image is allowing to scale without losing definition.
I have a published app that is crashing at startup on Android N when the newly introduced Display size OS setting is set to too large a value.
When I look in logcat, I see the following message:
java.lang.RuntimeException: Canvas: trying to draw too large(106,975,232 bytes) bitmap.
I've traced the issue to an ImageView in my first Activity that shows a nice big background image. The image in question is 2048x1066 and is in my generic drawables directory, so no matter the density, this image will be used.
Everything works okay when the Display size setting is Small. But when I go up to Default, it stops working. If I then swap the image out with a smaller one, it works at Default, but if I go up to Large, it stops working again.
My guess is that adjusting Display size up causes your device to behave like a physically smaller device with a higher pixel density. But I don't understand what I'm supposed to do here. If I put in progressively smaller images for progressively higher resolutions, it won't look good on actually large displays. Or am I not understanding something?
Any pointers would be greatly appreciated.
I my case, moving the (hi-res) splash bitmap from drawable to drawable-xxhdpi was the solution.
I had the same problem. I didn't suspect my splash screen to be the problem, since it is displayed when the app is started, but it turned out the splash screen is the problem.
The splash screen in my case has xxhdpi resolution, and it was mistakenly placed in the drawable folder, instead of drawable-xxhdpi. This made Android assume the splash screen had mdpi resolution and scale the image to 3*3 times it's required size and trying to create a bitmap.
I solved the problem after adding the below code into the Manifest file's application tag in between android: lines.
android:hardwareAccelerated="false"
I don't know would it help some one, but I'll just leave it here.
In my case - problem was only on Sumsung devices with Android 7, and problem was in splash screen proportions. after changing height to 1024 px - everything works fine
Move your image in the drawable to mipmap-xxhdpi.Your image is in bitmap format so you should put your image in mipmap folder,then it will work
There are some scenarios where Original Bitmap needs be Drawn into ImageViews, Photo Editing apps etc...,
as bay mentioned above setting
android:hardwareAccelerated="false"
will Cause bad UI experince, You can set hardwareAccelerated Only one selected Activity where high res image to be drawn
<application android:hardwareAccelerated="true">
<activity ... />
<activity android:hardwareAccelerated="false" />
</application>
Try to use Bitmap.Factory class, this link will help you
Loading Large Bitmaps Efficiently
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
The icon files are too large for Android to efficiently and smoothly load. Android recognizes this with its smart algorithms.
You can resize the icon files using Final Android Resizer by asystat. Resize them to "xhdpi" or lower.
Place the resized photos in drawable or overwrite over the existing large icon files.
Then, you're done.
if you are using glide and you are loading 1k of images at a time or some images then it is issue of glide or whatever you are doing to use to set the image view. you can resolve it just by applying scale type in glide.
In my case, I just changed the canvas of image which is used in the background using Paint3d(or you can use any other). Here I am sharing a screenshot just go through it.
it is solved by resizing the images to a lower size.
Need to add Manifest file's application tag in between android: add below lines.
android:hardwareAccelerated="false"
Just an addition to the Johan Franzén's answer, maybe it's a good idea to not only add drawable-xxhdpi density folder, but also add another density folder.
So whatever the android version and size, your app can prepare the image source with the right size :
Change your folder view on the top left from Android to Project
Go to YourProjectFolder folder > app > src > main > res
Prepare the original image with your best resolution, and split it into each folder size automatically. You can do it in Baker
Then create a folder with another density, namely:
drawable-hdpi, drawable-ldpi, drawable-mdpi, drawable-xhdpi, drawable-xxhdpi, drawable-xxxhdpi
Put each image into the appropriate folder
i solved the problem by simply changing the image extension to .png extension, and it worked just fine with me.
After finding Display SVG Image in image view in android on Google and going to Having issue on Real Device using vector image in android. SVG-android, I find that "You need a 3rd-party JAR to do it" is a bit of overkill. Is there any way to render an SVG without using 3rd-party libraries?
I managed to display an SVG using a WebView, since that is more than capable of rendering an SVG:
webView.loadUrl("file:///android_res/drawable/file.svg"); // point it to the SVG
webView.setBackgroundColor(0x00000000); // set the background to transparent
This makes it render much like a transparent PNG would in an ImageView. The only caveat is that the SVG must use the viewBox attribute and not use the height or width attributes, to ensure it resizes properly.
Using custom fonts actually works really well in Android.
You can use the free icomoon web application to convert SVGs to custom .ttf font characters.
If you are using it for imagePicker sort of feature then,
webView.loadURl(selectedFileLocation.toString)
else if it is to display a .svg image from web,
webView.loadURl(/*url for the .svg file*/)
I'm developing an application with phonegap(css3 + html5 + javascript) for iOS and Android 4.x.
On Android 4.0.3 device, I use with css a background image as button with this code:
.mycssClass
{
background-image:url(../images/myImage.png);
background-repeat:no-repeat;
background-size:100%;
background-color:transparent;
border:none;
font-weight:300;
....
}
Now, the image is displayed correctly, but if I hold down on the screen, it becomes grainy.
If I remove background-size:100%; solved the problem, but the image is not displayed in the correct size.
I add some code lines for managing anti-aliasing, based on the proposal of this aid
https://developer.mozilla.org/en-US/docs/CSS/image-rendering
without good result.
Any suggestions?
Thanks in advance,
Cristian
Your issue have solution.
Problem happens because of difference between antialiasing mechanisms in CSS engine and Android WebView component. CSS antialiases images before they were scaled and browser antialiasing is being applied after scaling.
To avoid this effect you have to disable scaling somehow.
There is good approach which allows to keep responsive images and avoid scaling. Replace your background with img tag and apply CanvasImage to them after page is loaded.
CanvasImage replaces img elements with canvases of same size as element is at the moment of execution so there will be no scaling.
Feel free to ping me if you will have any problems with this.
I am using a WebView in an Android Activity to show a simple html who has a single jpg inside. When the jpg height is smaller than 3000 pixels, there is no problem, it show perfectly, but when the jpg is above 3000 pixels, it does not show. Can be this a limitation? Or memory issue? I am using Android 2.3 to test.
Your problem is that you're using a huge image, so the device can't handle that much data.
In order to display it properly and nicely mi advice is to use an html table wich each cell containing a slice of the image.
The browser will just render the parts of the table being displayed, so your image will be loaded properly.
I used this approach on a project and worked perfectly.
Regards.