Please post working code for Android image resize
I've tried just about everything I could find on the forums to resize an image (from the device camera, for uploading to a server) without luck. If you have code that you know works with Appcelerator 1.4.1 on an Android device I'd be most appreciative if you'd post it.
Here's my latest attempt. It seems to do nothing - the returned image has the same dimensions as the input image.
function resize_image(image, max_width){
var reducedImageView = Titanium.UI.createImageView({
width: max_width
height: 'auto',
canScale: true,
image: image
});
return reducedImageView.toBlob();
}
Other things I've tried: toImage instead of toBlob crashes when I try to use the returned image:
09-24 14:02:14.197: ERROR/TiUncaughtHandler(16495): (main) [724,20151] Sending event: exception on thread: main msg:java.lang.IllegalArgumentException: width and height must be > 0
5 Answers
-
The argument
image
should be a UI.ImageView object.function resizeImage(image, maxWidth) { var tmp = image.toImage(); var wid = tmp.width; var ht = tmp.height; var reduction; if(wid > ht) { reduction = maxWidth / wid; wid = maxWidth; ht = Math.round(ht * reduction); } else { reduction = maxWidth / ht; ht = maxWidth; wid = Math.round(wid * reduction); } image = Ti.UI.createImageView({ image: tmp, width: wid, height: ht }); return image; };
-
I also tried using backgroundImage instead of image in the view. It crashes with both of toBlob and toImage.
-
Hi Parand,
my android app doesn't work in 1.4.1 for some reason so I'm still using 1.3 for android.
I've posted the full code here http://pastie.org/1180130 Its hard to remember what I did but I think I have 2 versions of the image. One that's displayed on screen for the user to see and another slightly larger one that gets uploaded to the server. I've included the rescale and upload functions, the upload function sends the data to a php script which returns a JSON stream indicating success.
Just gave it a quick test and they still work :) I hope they help you out.
-
There is a built in function to do this for iOS only but you'll need to make your own module, but here are two functions to perform the resize in a custom android module. Appcelerator folks, here's your prompt to just pull code into your repo for android users wanting the same functionality.
To future people reading this… sorry I can't share any more source than this. Good luck everyone!
... (Appcelerator module) ... //private utility function to create an image (in Ti) from a bitmap public KrollDict createDictForImage(Bitmap bmpInput) { KrollDict d = new KrollDict(); d.put("x", 0); d.put("y", 0); d.put("width", bmpInput.getWidth()); d.put("height", bmpInput.getHeight()); KrollDict cropRect = new KrollDict(); cropRect.put("x", 0); cropRect.put("y", 0); cropRect.put("width", bmpInput.getWidth()); cropRect.put("height", bmpInput.getHeight()); d.put("cropRect", cropRect); d.put("media", TiBlob.blobFromImage(getTiContext(), bmpInput)); return d; } //Methods @Kroll.method public KrollDict imageAsResized(@Kroll.argument(optional=false) KrollDict objImage, int iWidth, int iHeight) throws IOException, IllegalStateException { //decode the blob //if (blobInput.getType() != TiBlob.TYPE_IMAGE) { // throw new IOException("imageAsCropped::Input type of blob is not image"); //} if (!objImage.containsKeyAndNotNull("media") || !objImage.containsKeyAndNotNull("width") || !objImage.containsKeyAndNotNull("height")) { throw new IllegalStateException("imageAsCropped::Failed, unknown image type!"); } TiBlob blobInput = null; if (objImage.containsKey("media")) { Object media = objImage.get("media"); if (media instanceof TiBlob) { blobInput = (TiBlob) media; } } //decode the blob input byte[] byImage = blobInput.getBytes(); Bitmap bmpInput = BitmapFactory.decodeByteArray(byImage, 0, byImage.length); Log.d(LCAT, "imageAsResized::Decoded "+byImage.length+" bytes from input blob"); if (byImage.length==0 || bmpInput==null) { throw new IllegalStateException("imageAsCropped::Could not parse the input image in bytes"); } //otherwise scale the bitmap with some java code... Bitmap bmpScaled = Bitmap.createScaledBitmap(bmpInput, iWidth, iHeight, false); //convert the scaled version back into a blob return createDictForImage(bmpScaled); } //config is a set of floats (x,y,width,height) @Kroll.method public KrollDict imageAsCropped(@Kroll.argument(optional=false) KrollDict objImage, @Kroll.argument(optional=false) KrollDict config) throws IOException, IllegalStateException { double dX=0, dY=0, dWidth=0, dHeight=0; if (!objImage.containsKeyAndNotNull("media") || !objImage.containsKeyAndNotNull("width") || !objImage.containsKeyAndNotNull("height")) { throw new IllegalStateException("imageAsCropped::Failed, unknown image type!"); } TiBlob blobInput = null; if (objImage.containsKey("media")) { Object media = objImage.get("media"); if (media instanceof TiBlob) { blobInput = (TiBlob) media; } } //decode the blob //if (blobInput.getType() != TiBlob.TYPE_IMAGE) { // throw new IOException("imageAsCropped::Input type of blob is not image"); //} if (!config.containsKeyAndNotNull("x") || !config.containsKeyAndNotNull("y") || !config.containsKeyAndNotNull("width") || !config.containsKeyAndNotNull("height")) { throw new IllegalStateException("imageAsCropped::Failed, missing one parameter (x,y,width,height)"); } dX = config.getDouble("x"); dY = config.getDouble("y"); dWidth = config.getDouble("width"); dHeight = config.getDouble("height"); //parse input into a regular image... byte[] byImage = blobInput.getBytes(); Bitmap bmpInput = BitmapFactory.decodeByteArray(byImage, 0, byImage.length); Log.d(LCAT, "imageAsResized::Decoded "+byImage.length+" bytes from input blob"); if (byImage.length==0 || bmpInput==null) { throw new IllegalStateException("imageAsCropped::Could not parse the input image in bytes"); } // recreate the new Bitmap Bitmap bmpCropped = Bitmap.createBitmap(bmpInput, (int)dX, (int)dY, (int)dWidth, (int)dHeight); //convert the scaled version back into a blob return createDictForImage(bmpCropped); } ...
-
just had the same problem. try giving a different height, 'auto' doesn't work