I'm using library which takes bitmap.
At first I'm showing bitmap in ZoomableImageView. But after scale, zoom I need to send to the library only visible part of image view.
Here is my code to create scaled bitmap with matrix:
Bitmap result = Bitmap.createBitmap(originalBitmap, 0, 0, originalBitmap.getWidth(), originalBitmap.getHeight(), matrix, true);
However, the user may be constantly zooming in on the image, and what happens is that this code is executed frequently and my application freezes. Is there any way to prevent this or is there a better way to create scaled bitmap ?
Please help me.
Related
I'm currently working on an Android app. I have a canvas onto which the user will draw something. I need to have a picture as the background of this canvas.
I already managed to import a pic and set it as the background using
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_background_pic));
However, the picture appears ten times bigger than the screen.
Is it possible to keep the picture resized, so it fills the canvas and not more?
Also, later I will need to add other things to the activity. The canvas will not be the only thing on the screen, so I need the picture to be the size of the canvas, and not the screen.
Thanks a lot.
Nevermind I found it:
canvas.drawBitmap(bitmap, null, new RectF(0, 0, canvasWidth, canvasHeight), null);
By Kai at stackoverflow.com/a/27466127/8205282
I am trying to rotate a bitmap and crop out a valid Rectangle out of it, and then save it on the disk. What i am trying to do is explained in the following link:
http://i.stack.imgur.com/IIhBw.png
Black is the original image. Red is rotated image (by 15 degrees here) and green is the valid portion of the red image.
This feature is similar to the Image straightening which Instagram app does.
So far, I have tried this:
public static Bitmap getRotatedBitmap2(Bitmap bmp, int rotation){
Matrix matrix = new Matrix();
matrix.preRotate(rotation);
Bitmap bitmap = Bitmap.createBitmap(bmp, 0, 0,
bmp.getWidth(), bmp.getHeight(),
matrix, false);
return bitmap;
}
This rotates the bitmap but it shrinks in size, also the rotated bitmap is enclosed is an black rectangle. i need to get rid of the out-bounding black rectangle. Also, How can I obtain the valid portion of bitmap?
Aviary and ImageMagick are libraries that can help to achieve the results asked in the question, as well perform other Bitmap operations and Image Manipulations.
I know you already solved this question, but if somebody is looking for another solution, you can check this library image-rotator that solves problem like this or very similar.
I'm writing an android application.By using it,a user can crop the bitmap image.But I want to add more function,that is to rotate the image before cropping.
I followed the below steps to accomplish this purpose.
built a custom view.
initialized BitmapDrawable() and a cropping rectangle(Rect()) [the rectangle determines where to cop in the bitmap]
override onTouch(MotionEvent) method for two functions
a. user can move the bitmap over the screen
b. user can transform the cropping rectangle
override onDraw(Canvas) method to update the screen.This code is for showing bitmap.
bitmap_drawable.draw(canvas,_bitmap_paint);
Problem:1
This step ,that I don't know how to do, is to show a rotated properly. I used this code to rotate the canvas in the onDraw(Canvas) method.
canvas.rotate(_angle);
But it makes all the things on the screen (including the cropping rectangle) to rotate.
Question:2
Is it a wise way to initialize my own Canvas() object to draw the bitmap on?
Note:
Here,the rotation that I want,is very accurate up to 1 degree and is performed by two-finger rotation gesture so that performance is very important and the following code(using matrix) is bad.
Matrix mat = new Matrix();
mat.preRotate(_degree, _one_finger_x, _one_finger_y);
Bitmap _new_bitmap = Bitmap.createBitmap(_old_bitmap, 0, 0, bmWidth, bmHeight, mat, true);
Therefore,I think initializing a separate Canvas() and using canvas.rotate(_degree) is very appropriate.However,this makes controlling touch events quite difficult.Any ideas?Please help.
Problem:2
Suppose that I can now rotate the bitmap separately from all objects,i.e. the cropping rectangle,etc.This step is to crop the bitmap and show the cropped result to the user efficiently.When rotate function is not included, I simply copy the color bytes within the cropping rectangle on the old bitmap as follow.
Bitmap _new_bitmap = Bitmap.createBitmap( _old_bitmap, _cropRectx, _cropRecty, _cropRectWidth, _cropRectHeight, null);
But here,from a rotated bitmap, how can I clone the color bytes through a crossing crop rectangle?
Question:2
How can I crop a rotated bitmap?
I am working with large size images and when I try to rotate them (applying matrix on the bitmap) a lot of seconds occurs.
I've seen that android system gallery can accomplish this task in a very fast manner instead. How is it possible?
I thought to perform the rotation on an asyncTask, applying only the ImageView rotation (which doesn't take long time) on the main thread, but if the app is killed before the asyncTask get to the end, the app fall in an inconsistent state.
This is my bitmap rotation code, which takes long time execution for large bitmaps:
Matrix mat = new Matrix();
mat.setRotate(90);
bMap = Bitmap.createBitmap(bMap, 0, 0, bMap.getWidth(), bMap.getHeight(), mat, true);
When doing modifications to a large image, create a low quality bitmap copy of it and use it for showing instant rotation or other editing effects. Once user is stopped motion (or left slider control) replace the low quality bitmap with the original image with same effects applied to it. This will significantly improve user experience. Try and let me know.
This might sound like a deviation from the original requirement- you can draw a rectangle instead of rotating the whole image in real time. In the end, what user needs is an indication of how much his image has rotated. This will be faster and can easily be done on UI thread without lag.
This is the simplest rotation on canvas code
canvas.save(); //save the position of the canvas
canvas.rotate(angle, X + (imageW / 2), Y + (imageH / 2)); //rotate the canvas
canvas.drawBitmap(imageBmp, X, Y, null); //draw the image on the rotated canvas
canvas.restore(); // restore the canvas position.
I am using a Custom ImageView. In its onDraw I do some processing by using the canvas which is like drawing line, bitmaps based on user touch.
To save the resultant snapshot when the user want to save the image, we are using drawingCache
imageView.setDrawingCacheEnabled(true;
Bitmap.createBitmap(imageView.getDrawingCache(), 0, 0,
imageView.getHeight(), imageView.getWidth(),
matrix, true).compress(CompressFormat.JPEG, 95,
new FileOutputStream(file));
Of course I can use this to get the actual image while user presses save but the image does not contain any of the processing done on the imageView.
Bitmap bmp = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
Bitmap.createBitmap(bmp, 0, 0,
bmp.getWidth(), bmp.getHeight(),
matrix, true).compress(CompressFormat.JPEG, 95,
new FileOutputStream(file));
Problem:
The size of the image saved is the size of the imageView which is fullscreen but depends on the device. For smaller screen size phones it goes down to 240 X 320.
Question:
a. Is it possible to get a decent size image irrespective of the device screen size?
b. Is it possible to do Image Processing directly on the Image that is being used in the Custom ImageView?
Thanks in anticipation!
Any thoughts?
Maybe an alternative would be use the Canvas class to do some of your drawing and image display: javadoc: android.graphics.Canvas.
The ImageView class is not the best when images need to "refreshed" often.
If you decide to stick to ImageView, don't create the bitmap using the ImageView's dimensions. Retain the aspect ratio of the image, and compose your bitmap according to the big dimensions you need. The imageView will shrink it (if needed) to fit the screen.
You can use
Bitmap.createScaledBitmap(Bitmap b, int newWidth, int newHieght, boolean filter);
and to get a bitmap from resources use
Bitmap image = BitmapFactory.decodeResource(..)
you can then use
ImageView.setImageBitmap(Bitmap bm)
to set the new bitmap to the imageview