Android ImageView get bitmap after zoom using setImageMatrix - android

In Android I have an ImageView which user can manipulate the position and zoom level in the UI.
Is it possible to get the zoomed image (changed image) from the ImageView instead of original one.
Here are the methods I tried but no use.
imageView.buildDrawingCache(true);
Bitmap bmp = imageView.getDrawingCache(true);
I can get the Matrix but don't know how to use it.
Matrix m = imageView.getImageMatrix();

The zoom effect is applied at the Canvas level. So, what you can do is get the current Canvas augmentations and then draw your Bitmap into a new one with the changes.
Matrix transformMatrix = imageView.getImageMatrix()
Bitmap original = bmp;
Bitmap adjusted = Bitmap.createBitmap(original.getWidth(),
original.getHeight(),
original.getConfig());
Canvas canvas = new Canvas(adjusted);
canvas.setMatrix(transformMatrix);
canvas.drawBitmap(original, 0, 0, null);
//at this point adjusted bitmap contains the zoomed image

When you get a Matrix from an ImageView, make changes to t, then use imageView.setImageMatrix(m) apply the changes back to the ImageView. You will want to look into using one of the postScale() matrix methods to make a change in the size of image rendered.

Related

Android - Rotate a part of an Image

I basically need to rotate 90 degres a small part of an ImageView (e.g):
In the Image above, I'd like to rotate the 4 so it displays correctly. Only the 4, the rest should remain vertical as it is.
Is there a way I can achieve it?
By Implementing the method suggested by MikeM. I'm getting the following result.
As you can see there are two major things I need to fix:
The rotated square is working, although in the wring position. How do I found out the exact coordinates of the 4
The background of the image, has been changed to black. It used to be transparent
If you know, or can figure, the coordinates and dimensions of the region you'd like to rotate, then the process is relatively straightforward.
Load the image as a mutable Bitmap.
Create a second, rotated Bitmap of the desired region from the original.
Create a Canvas on the original Bitmap.
Clear the clipped area, if necessary.
Draw the rotated region back onto the original.
In the following example, it's assumed that the region's coordinates (x, y) and dimensions (width, height) are already known.
// Options necessary to create a mutable Bitmap from the decode
BitmapFactory.Options options = new BitmapFactory.Options();
options.inMutable = true;
// Load the Bitmap, here from a resource drawable
Bitmap bmp = BitmapFactory.decodeResource(getResources(), resId, options);
// Create a Matrix for 90° counterclockwise rotation
Matrix matrix = new Matrix();
matrix.postRotate(-90);
// Create a rotated Bitmap from the desired region of the original
Bitmap region = Bitmap.createBitmap(bmp, x, y, width, height, matrix, false);
// Create our Canvas on the original Bitmap
Canvas canvas = new Canvas(bmp);
// Create a Paint to clear the clipped region to transparent
Paint paint = new Paint();
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
// Clear the region
canvas.drawRect(x, y, x + width, y + height, paint);
// Draw the rotated Bitmap back to the original,
// concentric with the region's original coordinates
canvas.drawBitmap(region, x + width / 2f - height / 2f, y + height / 2f - width / 2f, null);
// Cleanup the secondary Bitmap
region.recycle();
// The resulting image is in bmp
imageView.setImageBitmap(bmp);
To address the concerns in the edit:
The rotated region's figures in the original example were based on the image with the long axis vertical. The image in the edit had been rotated to vertical after that region had been modified.
The black background was due to having inserted the resulting image into MediaStore, which saves images in the JPEG format, which does not support transparency.

How to combine two bitmaps into one so that their relative position should not be changed in rotating the combined one?

In my application,I want to combine two bitmaps for example a leaf and its shadow, in water.I am able to combine those bitmaps and make the combined bitmap freely fall from the top of the screen with some rotation in a live wallpaper.In my combined image the shadow is a little bit below the original leaf and left to it.If the combined image is rotating with some angle,the shadow also rotates with that angle.It seems to be like that the shadow is rotating like original image. But the shadow position should be always below the original image. But some times shadow is appearing on top of the original image while the combined image is falling with rotation because they are merged.I do not want this.I want the shadow always below the original image under any instance.How can i achieve this?Please help me.I am providing my code to combine the two bitmaps.
public static Bitmap overlay(Bitmap bmp1, Bitmap bmp2) {
Bitmap bmoverlay = null;
bmoverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig());
Canvas canvas = new Canvas(bmoverlay);
canvas.drawBitmap(bmp1, null, new Rect(0, 0, canvas.getWidth() , canvas.getHeight()), null);
canvas.drawBitmap(bmp2, 20, 20, null);
return bmoverlay;
}
Please suggest me how to do or any other method which does my requirement?Thanks in advance.

Zoom in and rotate simultaneously on seekbar in Android

I am working on a project where I need to ZoomIn and rotate the image simultaneously on seekbar progress value.
I have tried below code. But this is not working. This is just rotating the image.
Matrix matrix = new Matrix();
matrix.postRotate(curValue);
//matrix.postScale(curValue, curValue);
Bitmap resizedBitmap = Bitmap.createBitmap(bitmaprotate, 0, 0, bmpWidth, bmpHeight, matrix, true);
mainImage.setImageBitmap(resizedBitmap);
For achieving this you better to use custom view and canvas. Using canvas you can easily rotate and scale the images. Please refer this links (resize the bitmap canvas ,Android Scaling Canvas Bitmap , http://www.barebonescoder.com/2010/06/android-development-simple-2d-graphics-part-1/)

Android: Canvas gives garbage when shifting a Bitmap?

I would like to use Canvas to "shift a bitmap"; to create a Bitmap from a Bitmap, but with a y offset such that all the pixels in the Bitmap are either shifted down (with blank pixels at the top) or shifted up (with blank pixels at the bottom). I am using the below code to do this. The code works fine as long as I am shifting up (shiftY is negative), but it gives a garbage bitmap if I try to shift down.
The second set of code is my work around for this, but this has the very undesirable effect of doubling my memory usage.
Is there any way to shift a Bitmap whitout using a second Bitmap?
//create canvas from the current Bitmap.
Canvas canvas = new Canvas (m_Bitmap);
/*draw into the current Bitmap into the canvas with an offset, thereby drawing over itself
shifted pixels*/
canvas.drawBitmap(m_Bitmap, 0, shiftY, null);
`
//create the canvas from a temp bitmap
Canvas canvas = new Canvas (m_2ndBitmap);
//draw the shifted pixels into the temp bitmap
canvas.drawBitmap(m_BackBuffer, shiftX, shiftY, null);
//swap the bitmaps
Bitmap temp = m_Bitmap;
m_Bitmap = m_2ndBitmap;
m_2ndBitmap = temp;
You can do it yourself if you copy row by row from the bottom. The problem is that your source and destination are the same and it's copying from the top, destroying the rows beneath before you can copy them lower.
When you are referencing a "new" or new Bitmap to an already existing Bitmap, the already existing Bitmap will be available for garbage collection.
However, do not create objects during runtime: just use two Bitmaps that you are allocating up front, when your Canvas has been created and skip creating the new Canvas.
Try:
canvas.drawBitmap(Bitmap.createBitmap(m_BackBuffer), shiftX, shiftY, null);
instead of:
canvas.drawBitmap(m_BackBuffer, shiftX, shiftY, null);

can an image be manipulated using canvas

Is it possible to manipulate images using canvas? How do we get the image onto the canvas?
#Override
protected void onDraw(Canvas canvas) {
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
Bitmap mBitmap = bitmap.copy(bitmap.getConfig(), true);
canvas = new Canvas(mBitmap);
Matrix matrix = new Matrix();
canvas.drawBitmap(mBitmap, matrix, mPaint);
}
I'm unable to see the image on the screen. canvas.drawBitmap() shouldn't be necessary since I'm using the constructor and passing mBitmap.
Yes you can, but you don't "get the image onto the Canvas," a Canvas is just an interface to draw onto a Bitmap. To do so, simply create a Canvas and give a reference to your mutable Bitmap:
Canvas c = new Canvas(myBitmap);
Very easy :)
You shouldn't do this in your onDraw method. Try to create an ImageView that should display the image and then set the bitmap via setImageBitmap(bitmap).
In general you are doing somethings wrong in your code.
Loading an image every time something should be drawn to the screen will slow down your application a lot. Try to load the image only once and then just edit and set it to the imageview.
You are assigning a new Canvas to the parameter you got. But this won't change anything on the screen. Think of it like somebody puts a paper in front of you and says:"Please write your message on the paper". Now you take another blank paper and write on it. But the other person only knows about his paper and will use this paper to read your message.

Categories

Resources