Rotate bitmap multiple times makes image blur how to avoid it - android

I wanted to rotate the images as much as the user clicks on rotate button.The code below makes the image rotated correctly but my image is becoming blur.
I've been using the code below:
backLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for(int i=0;i<selectedImageList.size();i++) {
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
Bitmap scaledBitmap = BitmapFactory.decodeFile(selectedImageList.get(i), bmOptions);
Matrix matrix=new Matrix();
matrix.preRotate(0);
Bitmap rotatedBitmap = Bitmap.
createBitmap(scaledBitmap , 0, 0, scaledBitmap .getWidth(), scaledBitmap .getHeight(), matrix, true);
File file=Utility.createFileFromBitmap(rotatedBitmap);
File oldFile=new File(selectedImageList.get(i));
LogUtil.error("Deleted Name",oldFile.getAbsolutePath()+"-->"+file.getAbsolutePath());
oldFile.delete();
itemList.set(selectedImages.get(i),file.getAbsolutePath());
selectedImageList.set(i,file.getAbsolutePath());
mSnapRecyclerAdapter.notifyDataSetChanged();
}

Matrix matrix = new Matrix();
imageView.setScaleType(ImageView.ScaleType.MATRIX); //required
matrix.postRotate((float) angle, pivotX, pivotY);
imageView.setImageMatrix(matrix);
/
#Override
public void onClick(View v)
{
imageView.setRotation(imageView.getRotation() + 90);
}

Related

Scaling the image and setting in Image View reduces image quality and squeezes it

I am tying to make a custom camera and after taking picture I am setting it in image view in the same activity as in which I am setting camera. I have been successful in taking the photos but before setting the image in image view I have to scale it which reduces the image quality. Is there any way to show the real image instead of scaling it?
My images are as below First one is real view of camera which is surface view:
After Taking photo it becomes:
The code I am using is:
Camera.PictureCallback picture = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
mCamera.stopPreview();
surface_view.setVisibility(View.INVISIBLE);
setupImageDisplay(data);
}
};
private void setupImageDisplay(byte[] data) {
photo = BitmapFactory.decodeByteArray(data, 0, data.length);
photo = scaleDown(photo, true);//scaling down bitmap
imageview_photo.setImageBitmap(photo); //setting bitmap in imageview
}
public Bitmap scaleDown(Bitmap realImage, boolean filter) {
int screenWidth = width;
int screenHeight = height;
Bitmap scaled;
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
// Notice that width and height are reversed
scaled = Bitmap.createScaledBitmap(realImage, screenHeight, screenWidth, filter);
int w = scaled.getWidth();
int h = scaled.getHeight();
// Setting post rotate to 90
Matrix mtx = new Matrix();
if (camera_id == Camera.CameraInfo.CAMERA_FACING_FRONT) {
float[] mirrorY = {-1, 0, 0, 0, 1, 0, 0, 0, 1};
Matrix matrixMirrorY = new Matrix();
matrixMirrorY.setValues(mirrorY);
mtx.postConcat(matrixMirrorY);
}
mtx.postRotate(90);
// Rotating Bitmap
realImage = Bitmap.createBitmap(scaled, 0, 0, w, h, mtx, filter);
} else {// LANDSCAPE MODE
//No need to reverse width and height
scaled = Bitmap.createScaledBitmap(realImage, screenHeight, screenWidth, filter);
int w = scaled.getWidth();
int h = scaled.getHeight();
// Setting post rotate to 90
Matrix mtx = new Matrix();
if (camera_id == Camera.CameraInfo.CAMERA_FACING_FRONT) {
float[] mirrorY = {-1, 0, 0, 0, 1, 0, 0, 0, 1};
Matrix matrixMirrorY = new Matrix();
matrixMirrorY.setValues(mirrorY);
mtx.postConcat(matrixMirrorY);
}
mtx.postRotate(180);
// Rotating Bitmap
realImage = Bitmap.createBitmap(scaled, 0, 0, w, h, mtx, filter);
}
return realImage;
}
After taking photo the image is like squeezed is there any way that image remains the same after scaling?
You can create a separate file which is temporary file and stores the thumbnail size of the image. You can make a POJO like this to store both images. You can display the smaller one and use the original file to keep high quality.
public class Image {
File fullSize;
File Thumbnail;
public Image(File fullSize, File thumbnail) {
this.fullSize = fullSize;
Thumbnail = thumbnail;
}
public File getFullSize() {
return fullSize;
}
public void setFullSize(File fullSize) {
this.fullSize = fullSize;
}
public File getThumbnail() {
return Thumbnail;
}
public void setThumbnail(File thumbnail) {
Thumbnail = thumbnail;
}
}

Rotate custom view in 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;

poor image quality after saving rotated bitmap to sdcard

I am making an app where in one of the activity i am fetching image from gallery and showing it in adapter like image below
I have to rotate that image and save it to sdcard. My code is doing fine but after saving it to sdcard i get very poor quality of image. my code is:
viewHolder.imgViewRotate.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
imagePosition = (Integer) v.getTag();
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap rotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
try {
FileOutputStream out = new FileOutputStream(new File(uriList.get(rotatePosition).toString()));
rotated.compress(Bitmap.CompressFormat.PNG, 100, out);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
notifyDataSetChanged();
}
});
Any suggestions will be great help.
Try out below code to reduce image size without losing its quality:
public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth)
{
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
EDITED:
Resize the image using BitmapFactory inSampleSize option and the image doesn't lose quality at all. Code:
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
Bitmap bm = BitmapFactory.decodeFile(tempDir+"/"+photo1_path , bmpFactoryOptions);
int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)600);
int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)800);
if (heightRatio > 1 || widthRatio > 1)
{
if (heightRatio > widthRatio){
bmpFactoryOptions.inSampleSize = heightRatio;
} else {
bmpFactoryOptions.inSampleSize = widthRatio;
}
}
bmpFactoryOptions.inJustDecodeBounds = false;
bm = BitmapFactory.decodeFile(tempDir+"/"+photo1_path, bmpFactoryOptions);
// recreate the new Bitmap
src = Bitmap.createBitmap(bm, 0, 0,bm.getWidth(), bm.getHeight(), matrix, true);
src.compress(Bitmap.CompressFormat.PNG, 100, out);

Android Camera in Portrait on SurfaceView and save the Snapshot

my api is 2.2,so i used camera.setDisplayOrientation(90) to make the preview is Portrait,this work very well,but when i save the pic to sd,the pic is horizontal not Portrait.when i used :
#Override
protected Bitmap doInBackground(String... params) {
int w = bmp.getWidth();
int h = bmp.getHeight();
// Setting post rotate to 90
Matrix mtx = new Matrix();
mtx.postRotate(90);
// Rotating Bitmap
Bitmap rotatedBMP = Bitmap.createBitmap(bmp, 0, 0, w, h, mtx, true);
bmp.recycle();
return rotatedBMP;
}
#Override
protected void onPostExecute(Bitmap result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
dialog.dismiss();
ivNewPhoto.setImageBitmap(result);
resultPath = ConstValue.MY_ALBUM_DIR + "/" + System.currentTimeMillis() + ".jpg";
ImageFile.writePhotoJpg(result), resultPath);
previewView.setVisibility(View.VISIBLE);
}
bmp is the Snapshot pic but i have mistakes:
Activity com.android.SuperPictureSearch.photo.PhotoActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView#43abb200 that was originally added here
can you tell me how to save the pic is Portrait,thank you
public void onPictureTaken(byte[] data, Camera camera) {
Bitmap mutableBitmap = null;
BitmapFactory.Options options = new BitmapFactory.Options();
Bitmap bm= BitmapFactory.decodeByteArray(data, 0, data.length, options);
mutableBitmap =Bitmap.createScaledBitmap( bm , h, w,true);
bm.recycle();
Matrix matri = new Matrix();
matri.postRotate(90);
Bitmap mBitmap = Bitmap.createBitmap(mutableBitmap, 0, 0, mutableBitmap.getWidth(), mutableBitmap.getHeight(), matri, true);
mutableBitmap.recycle();
because the pic is too big form camera,so i size it

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