Is there any way or external library that can resize image using Lanczos (ideally) or at least bicubic alg. under Android? (faster is better of course, but quality is priority, a processing time is secondary)
Everything what I've got so far is this:
Bitmap resized = Bitmap.createScaledBitmap(yourBitmap, newWidth, newHeight, true);
However it uses bilinear filter and the output quality is terrible. Especially if you want to preserve details (like thin lines or readable texts).
There are many good libraries for Java as discussed for example here: Java - resize image without losing quality
However it's always depended on Java awt classes like java.awt.image.BufferedImage
, so it can't be used in Android.
Is there a way how to change the default (bilinear) filter in Bitmap.createScaledBitmap()
method or some library like Morten Nobel's lib that is able to work with android.graphics.Bitmap
class (or with some raw representation, as @Tron in the comment has pointed out)?
Here is code that I've used for resize the image..
Hope it will help you..
The most promising IMO is to use libswscale (from FFmpeg), it offers Lanczos and many other filters. To access
Bitmap
buffer from native code you can use jnigraphics. This approach guarantees nice performance and reliable results.EDIT
Here you can find rough demo app, that uses proposed approach. At the moment performance is frustratingly bad, so it should be investigated to decide if we to do something to improve it.
If you just want to resample the image in a way that is optimized for display purposes you can use this nifty little one liner that has served me well.
This line of code may seem strange because you're converting a bitmap to a BitmapDrawable and back to a bitmap again but a BitmapDrawable defaults to the device's pixel density (unless you use a different constructor).
If you need to resize also then just separate it into two lines and use setBounds before converting the BitmapDrawable back to a bitmap like so:
Bitmap drawable may be listed as depricated but it's not, only certain constructors are depricated and the constructor in this above example is not depricated. Also this will work with API 4
Alternativly the android docs have a downloadable sample for this here: https://developer.android.com/topic/performance/graphics/load-bitmap.html
Hope this helps.
Unfortunately Android uses android.graphics.Bitmap which does not exist in java while java uses java.awt.image.BufferedImage that does not exist in android :-(
I donot have
a ready to use library for android
but a path how to port a java-awt specific lib to a platform independat java lib with platfrom specific handlers for android and awt/j2seIn the java rescale lib you have to hide all java-awt specific classes (like BufferedImage) behind an interface
IBitmap
and implement that interface for j2se and independantly for Android.I have done this successfully for exif/icc/ipc metadata processing and implemented interface pixymeta-lib/.../IBitmap.java with implementation for j2se pixymeta-j2se-lib/.../j2se/BitmapNative.java and android pixymeta-android-lib/.../android/BitmapNative.java
So I have these packages
IBitmap
interfaceIBitmap
IBitmap
I recently wrote this to scale/crop an image to a specific resolution and compress it with quality:
it's not using the libraries you mentioned but it works and I am happy with it. Maybe you are, too.