Rotate custom view in android - android

I am trying to rotate an image. Rotation is perfectly working but when I get that rotated image back getting some blank space. What should I do for remove that blank space?
I have tried this code:
public static Bitmap RotateBitmap(Bitmap source, float angle) {
Matrix matrix = new Matrix();
matrix.setRotate(90, 0, 0);
matrix.postTranslate(source.getHeight(), 0);
// matrix.postRotate(angle);
return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
}
Utility.tempBitmap = RotateBitmap(Utility.tempBitmap, -90);

I solved my problem by changing in view set bitmap some changes as per my requirement. using this code :
the code i used before (Gives me white space)
public static Bitmap RotateBitmap(Bitmap source, float angle) {
Matrix matrix = new Matrix();
matrix.setRotate(90, 0, 0);
matrix.postTranslate(source.getHeight(), 0);
// matrix.postRotate(angle);
return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
}
Utility.tempBitmap = RotateBitmap(Utility.tempBitmap, -90);
Solution code is here:
public int setBitmap(final Bitmap bitmap)
{
changeBitmapContrastBrightness(1, 50);
gapRect = new RectF();
dest = new Rect();
setBackgroundColor(Color.GRAY);
if (bitmap.getWidth() > bitmap.getHeight()) {
this.mbitmap = bitmap;
invalidate();
return 0;
}
this.mbitmap = bitmap;
invalidate();
return 1;

Related

android - Not just align but cut off image using setPolyToPoly()

There is an objective to transform quadrilateral region (set by 4 points) of image into rectangle image. With Matrix.setPolyToPoly() and Bitmap.createBitmap() I can align whole image so points form a rectangle but now I dont know where is it's left-top corner so I can't cut it off.
For example let's say 4 points are corners of flag (teal color is just a background of ImageView):
Here is code with hardcoded values to fit flag to 72x48 Bitmap.
int w = 72;
int h = 48;
float src[] = {108, 201,
532, 26,
554, 301,
55, 372};
float dst[] = {0, 0,
w, 0,
w, h,
0, h};
Matrix m = new Matrix();
m.setPolyToPoly(src, 0, dst, 0, dst.length >> 1);
Bitmap b1 = BitmapFactory.decodeResource(getResources(), R.drawable.img);
ImageView iv1 = findViewById(R.id.testImg1);
iv1.setImageBitmap(b1);
Bitmap b2 = Bitmap.createBitmap(b1, 0, 0, b1.getWidth(), b1.getHeight(), m, true);
ImageView iv2 = findViewById(R.id.testImg2);
iv2.setImageBitmap(b2);
//these coordinates are hand-picked
Bitmap b3 = Bitmap.createBitmap(b2, 132, 208, w, h);
ImageView iv3 = findViewById(R.id.testImg3);
iv3.setImageBitmap(b3);
And original image (be sure you save it to res/drawable-nodpi):
As #pskink didn't post his answer, I do it.
To make new Bitmap and save original one - is exactly what I need, so here is solution for me:
int w = 72;
int h = 48;
float srcPoints[] = {108, 201,
532, 26,
554, 301,
55, 372};
float dstPoints[] = {0, 0,
w, 0,
w, h,
0, h};
Matrix m = new Matrix();
m.setPolyToPoly(srcPoints, 0, dstPoints, 0, dstPoints.length >> 1);
Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.macedonia);
Bitmap dstBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(dstBitmap);
canvas.clipRect(0, 0, w, h);
canvas.drawBitmap(srcBitmap, m, null);
But if you don't want to use extra memory, use other approach:
class BD extends BitmapDrawable {
Matrix matrix = new Matrix();
int w = 72;
int h = 48;
RectF clip = new RectF(0, 0, w, h);
public BD(Resources res, int resId) {
super(res, BitmapFactory.decodeResource(res, resId));
float src[] = {108,201,532,26,554,301,55,372};
float dst[] = {0,0,w,0,w,h,0,h};
matrix.setPolyToPoly(src, 0, dst, 0, src.length / 2);
}
#Override public int getIntrinsicWidth() {return w;}
#Override public int getIntrinsicHeight() {return h;}
#Override
public void draw(Canvas canvas) {
canvas.clipRect(clip);
canvas.drawBitmap(getBitmap(), matrix, null);
}
}

Default black border in Canvas with Bitmap

I want to use Bitmap with rounded using Canvas, but getting black border by default.
How can I remove this border.
Code
public Bitmap transform(final Bitmap source)
{
Drawable drawable = context.getResources().getDrawable(R.drawable.dummy_image);
float scale = Math.min(((float)drawable.getIntrinsicHeight() / source.getWidth()), ((float) drawable.getIntrinsicWidth() / source.getHeight()));
Matrix matrix = new Matrix();
matrix.postScale(scale, scale);
Bitmap newBitmap = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
final Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(new BitmapShader(newBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
Bitmap output = Bitmap.createBitmap(drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
canvas.drawCircle((drawable.getIntrinsicWidth())/2,(drawable.getIntrinsicHeight())/2, getDrawableSize()-24, paint);
if (source != output)
{
source.recycle();
}
return output;
}

Android Canvas How to scale Bitmap but keep original bound?

I want to scale a Bitmap using Canvas
I need to keep the Bitmap original width and height
and the scaled one aligns center-middle in bound
here is what I have tried:
public Bitmap scale(Bitmap src) {
int width = src.getWidth();
int height = src.getHeight();
float scaledWidth = width * .5f;
float scaledHeight = height * .5f;
Bitmap transBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(transBitmap);
Paint paint = new Paint();
float dx = (width - scaledWidth);
float dy = (height - scaledHeight);
canvas.drawBitmap(src, null, new RectF(dx, dy, scaledWidth, scaledHeight), paint);
Matrix m = new Matrix();
m.setRectToRect(new RectF(0, 0, src.getWidth(), src.getHeight()), new RectF(0, 0, scaledWidth, scaledHeight), Matrix.ScaleToFit.CENTER);
Bitmap output = Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), m, true);
//return transBitmap;
return output;
}
I used this method in custom ImageView onTouch:
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
setImageBitmap(scaledBmp);
break;
case MotionEvent.ACTION_UP:
setImageDrawable(originalDrawable);
break;
}
UPDATE
MyImageView.java
public class MyImageView extends ImageView {
private Drawable mDrawable;
private Drawable mScaled;
public MyImageView(Context context, Drawable drawable) {
super(context);
setImageDrawable(drawable);
Bitmap src = ((BitmapDrawable) drawable).getBitmap();
mDrawable = drawable;
mScaled = new BitmapDrawable(getResources(), makeScaled(src));
}
public Bitmap makeScaled(Bitmap src) {
int width = src.getWidth();
int height = src.getHeight();
float scaledWidth = width * .95f;
float scaledHeight = height * .95f;
Matrix m = new Matrix();
m.setRectToRect(new RectF(0, 0, src.getWidth(), src.getHeight()), new RectF(0, 0, scaledWidth, scaledHeight), Matrix.ScaleToFit.CENTER);
Bitmap output = Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), m, true);
Canvas xfas = new Canvas(output);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
xfas.drawBitmap(output, 0, 0, paint);
return output;
}
#Override public boolean dispatchTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
setImageDrawable(mScaled);
break;
case MotionEvent.ACTION_UP:
setImageDrawable(mDrawable);
break;
}
return super.dispatchTouchEvent(event);
}
}
If I have not misunderstood, one solution is to use a Matrix and its setRectToRect to translate the original values to the desired one. From the documentation
Set the matrix to the scale and translate values that map the source
rectangle to the destination rectangle, returning true if the the
result can be represented.
Matrix m = new Matrix();
m.setRectToRect(new RectF(0, 0, src.getWidth(), src.getHeight()), new RectF(0, 0, scaledWidth, scaledHeigth), Matrix.ScaleToFit.CENTER);
Bitmap output = Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), m, true);
and then simply draw the scaled bitmap on your canvas
Solved
public static Bitmap scaleBitmap(Bitmap src, float factor) {
int width = src.getWidth();
int height = src.getHeight();
int scaledWidth = (int) (width * factor);
int scaledHeight = (int) (height * factor);
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Bitmap scaled = Bitmap.createScaledBitmap(src, scaledWidth, scaledHeight, false);
Canvas canvas = new Canvas(bmp);
Paint paint = new Paint();
int distX = (width - scaledWidth) / 2;
int distY = (height - scaledHeight) / 2;
canvas.drawBitmap(scaled, distX, distY, paint);
return bmp;
}

Set a matrix on bitmap

Hy,
I want set only matrix in this code but if i use this statemant , it reset all drawing picture.
Bitmap a= Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix, true);
a need only new matrix but how i get it
I want only:
public static Bitmap flip(Bitmap src, int type) {
// create new matrix for transformation
Matrix matrix = new Matrix();
// if vertical
if(type == FLIP_VERTICAL) {
// y = y * -1
matrix.preScale(1.0f, -1.0f);
}
// if horizonal
else if(type == FLIP_HORIZONTAL) {
// x = x * -1
matrix.preScale(-1.0f, 1.0f);
// unknown type
} else {
return null;
}
// return transformed image
//Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix, true);
Bitmap pp= Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix, true);
return pp;
}
If oyu saw this Bitmao pp= ...
I want only change src ->matrix and that is all

Rotate image in android

I want rotate image in both the ways Clockwise as well as Anti clock wise.
I had try but not rotate image both the way,
so plz give me solution for my problem if you know..
Thanks in Advance.................///
Use the code below
public class Rotateimage extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gallery);
// or just load a resource from the res/drawable directory:
Bitmap myBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.flo);
// find the width and height of the screen:
Display d = getWindowManager().getDefaultDisplay();
int x = d.getWidth();
int y = d.getHeight();
// get a reference to the ImageView component that will display the image:
ImageView img1 = (ImageView)findViewById(R.id.imageView1);
// scale it to fit the screen, x and y swapped because my image is wider than it is tall
Bitmap scaledBitmap = Bitmap.createScaledBitmap(myBitmap, y, x, true);
// create a matrix object
Matrix matrix = new Matrix();
matrix.postRotate(45, 90, 180);
// create a new bitmap from the original using the matrix to transform the result
Bitmap rotatedBitmap = Bitmap.createBitmap(scaledBitmap , 0, 0, scaledBitmap .getWidth(), scaledBitmap .getHeight(), matrix, true);
// display the rotated bitmap
img1.setImageBitmap(rotatedBitmap);
}}
Here is the base code to load a bitmap and rotate it left or right:
// Load a bitmap from a drawable, make sure this drawable exists in your project
Bitmap sprite = BitmapFactory.decodeResource(this.getResources(),
R.drawable.ic_launcher);
// Create two matrices that will be used to rotate the bitmap
Matrix rotateRight = new Matrix();
Matrix rotateLeft = new Matrix();
// Set the matrices with the desired rotation 90 or -90 degrees
rotateRight.preRotate(90);
rotateLeft.preRotate(-90);
// Create bitmaps based on the loaded bitmap 'sprite' and apply one of
// the rotation matrices
Bitmap rSprite = Bitmap.createBitmap(sprite, 0, 0,
sprite.getWidth(), sprite.getHeight(), rotateRight, true);
Bitmap lSprite = Bitmap.createBitmap(sprite, 0, 0,
sprite.getWidth(), sprite.getHeight(), rotateLeft, true);
Now go and use rSprite and lSprite.
Here is a full sample that actually draws the bitmaps to screen:
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new drawView(this));
}
private class drawView extends View{
public drawView(Context context){
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Load a bitmap from a drawable, make sure this drawable exists in your project
Bitmap sprite = BitmapFactory.decodeResource(this.getResources(),
R.drawable.ic_launcher);
// Create two matrices that will be used to rotate the bitmap
Matrix rotateRight = new Matrix();
Matrix rotateLeft = new Matrix();
// Set the matrices with the desired rotation 90 or -90 degrees
rotateRight.preRotate(90);
rotateLeft.preRotate(-90);
// Create bitmaps based on the loaded bitmap 'sprite' and apply one of
// the rotation matrices
Bitmap rSprite = Bitmap.createBitmap(sprite, 0, 0,
sprite.getWidth(), sprite.getHeight(), rotateRight, true);
Bitmap lSprite = Bitmap.createBitmap(sprite, 0, 0,
sprite.getWidth(), sprite.getHeight(), rotateLeft, true);
//Draw the first unrotated sprite at the top left of the screen
canvas.drawBitmap(sprite, 0, 0, null);
//Draw the rotated right sprite on the 2nd row
canvas.drawBitmap(rSprite, 0, sprite.getHeight() + 5, null);
//Draw the rotated left sprite on the 3rd row
canvas.drawBitmap(lSprite, 0, sprite.getHeight() * 2 + 5, null);
}
}
}
use this code hope it will be helpful...
you must have to write this method to do rotate operation
public void paintFromCenter(float angle, Canvas c) {
Bitmap b = sprite;
Bitmap h = b;
Matrix matrix = new Matrix();
matrix.postRotate(angle, h.getWidth() / 2, h.getHeight());
matrix.postTranslate(getX(), getY());
// canvas.drawBitmap(bitmap, matrix, new Paint());
Bitmap bmp2 = Bitmap.createBitmap(h, 0, 0, frameWidth, frameHeight,
matrix, true);
c.drawBitmap(h, matrix, null);
}
in your program you have to write onTouchEvent() method
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN) {
edX = (int) event.getX();
edY = (int) event.getY();
if ((edX > objectSprite.getX()
&& edX < objectSprite.getX() + objectSprite.getWidth()
&& edY > objectSprite.getY() && edY < objectSprite.getY()
+ objectSprite.getHeight())) {
}
}
if (action == MotionEvent.ACTION_MOVE) {
emX = (int) event.getX();
emY = (int) event.getY();
if (edX < emX && angle <= 90) {
update(canvas);
CHAR = 'D';
} else if (edX > emX && angle > 0) {
update(canvas);
CHAR = 'U';
}
if (edY < emY && angle <= 90) {
update(canvas);
CHAR = 'L';
} else if (edY > emY && angle >= 0) {
update(canvas);
CHAR = 'R';
}
}
return true;
}
and you have to create update() method to rotate your angle on touch event angle can be define as your choice. Initially i have declare
int angle=1;
public void update(Canvas canvas) {
switch (CHAR) {
case 'D':
angle += 1;
break;
case 'U':
angle -= 1;
break;
case 'R':
angle -= 1;
break;
case 'L':
angle += 1;
break;
}
}
Now you have to draw your object in draw() method like this
public void draw() {
objectSprite.paintFromCenter(angle, canvas);
}
You just add this simple code to your button
imVCature_pic.setRotation(imVCature_pic.getRotation() + 90);
Matrix mat = new Matrix();
mat.preRotate(angle);///in degree
Bitmap mBitmap = Bitmap.createBitmap(originalBmp, 0, 0, modWidth, modHeight, mat, true);
//originalBmp -> original img as bitmap
//modHeight -> new height
//modWidth -> new width
use the above code.

Categories

Resources