[英]Crop image in Android using perfect aspect ratio
我一直在開發一個安卓應用程序。 我的應用程序中有一個功能需要具有設備屏幕精確尺寸的圖像,為此我正在使用此代碼,
Intent cropIntent = new Intent("com.android.camera.action.CROP");
cropIntent.setDataAndType(picUri, "image/*");
cropIntent.putExtra("crop", "true");
cropIntent.putExtra("aspectX", 0);
cropIntent.putExtra("aspectY", 0);
cropIntent.putExtra("outputX", width);
cropIntent.putExtra("outputY", height);
cropIntent.putExtra("return-data", true);
但此代碼的問題在於,由於寬高比已設置為零,因此在某些設備(如三星)中,裁剪窗口為正方形大小且無法調整。 那么我如何在 aspectX 和 aspectY 字段中設置寬高比,這樣圖像裁剪就沒有問題了,
我還編寫了一個 java 程序來計算縱橫比,但它似乎不適用於所有分辨率。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
class AspectRatio
{ public static void main(String args[])
{ BufferedReader buff=new BufferedReader(new InputStreamReader(System.in));
int width=0,height=0;
try
{ System.out.print("Enter the width of the screen:");
width=Integer.parseInt(buff.readLine());
System.out.println("Enter the height of the screen:");
height=Integer.parseInt(buff.readLine());
}
catch(IOException e)
{ e.printStackTrace();
}
int factor=0;
for(int i=2;i<new AspectRatio().minimum(width,height)/2;i++)
{ if(width%i==0&&height%1==0)
{ factor=i;
}
}
System.out.println("The aspect ratio is:"+width/factor+":"+height/factor);
}
public int minimum(int a,int b)
{ return (a<b?a:b);
}
}
您可以使用下一個類從系統獲取寬度和高度: DisplayMetrics
檢查鏈接它還將給出如何使用此類的示例..
這是我的助手類,用於以完美比例縮小任何圖像,它適用於從相機拍攝的圖像和設備上的 img:
public class ImageUtils {
private static final String TAG = "ImageUtils";
private static final float maxHeight = 1280.0f;
private static final float maxWidth = 1280.0f;
public static byte[] compressImage(String imagePath) {
Bitmap scaledBitmap = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bmp = BitmapFactory.decodeFile(imagePath, options);
int actualHeight = options.outHeight;
int actualWidth = options.outWidth;
float imgRatio = (float) actualWidth / (float) actualHeight;
float maxRatio = maxWidth / maxHeight;
if (actualHeight > maxHeight || actualWidth > maxWidth) {
if (imgRatio < maxRatio) {
imgRatio = maxHeight / actualHeight;
actualWidth = (int) (imgRatio * actualWidth);
actualHeight = (int) maxHeight;
} else if (imgRatio > maxRatio) {
imgRatio = maxWidth / actualWidth;
actualHeight = (int) (imgRatio * actualHeight);
actualWidth = (int) maxWidth;
} else {
actualHeight = (int) maxHeight;
actualWidth = (int) maxWidth;
}
}
options.inSampleSize = ImageUtils.calculateInSampleSize(options, actualWidth, actualHeight);
options.inJustDecodeBounds = false;
options.inDither = false;
options.inPurgeable = true;
options.inInputShareable = true;
options.inTempStorage = new byte[16 * 1024];
try {
bmp = BitmapFactory.decodeFile(imagePath, options);
} catch (OutOfMemoryError exception) {
exception.printStackTrace();
}
try {
scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888);
} catch (OutOfMemoryError exception) {
exception.printStackTrace();
}
float ratioX = actualWidth / (float) options.outWidth;
float ratioY = actualHeight / (float) options.outHeight;
float middleX = actualWidth / 2.0f;
float middleY = actualHeight / 2.0f;
Matrix scaleMatrix = new Matrix();
scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);
Canvas canvas = new Canvas(scaledBitmap);
canvas.setMatrix(scaleMatrix);
canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));
ExifInterface exif;
try {
exif = new ExifInterface(imagePath);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
Matrix matrix = new Matrix();
if (orientation == 6) {
matrix.postRotate(90);
} else if (orientation == 3) {
matrix.postRotate(180);
} else if (orientation == 8) {
matrix.postRotate(270);
}
scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
} catch (IOException e) {
e.printStackTrace();
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 85, out);
return out.toByteArray();
}
public static boolean compressImage(Bitmap image, FileOutputStream fos){
Bitmap scaledBitmap = null;
int actualHeight = image.getHeight();
int actualWidth = image.getWidth();
float imgRatio = (float) actualWidth / (float) actualHeight;
float maxRatio = maxWidth / maxHeight;
if (actualHeight > maxHeight || actualWidth > maxWidth) {
if (imgRatio < maxRatio) {
imgRatio = maxHeight / actualHeight;
actualWidth = (int) (imgRatio * actualWidth);
actualHeight = (int) maxHeight;
} else if (imgRatio > maxRatio) {
imgRatio = maxWidth / actualWidth;
actualHeight = (int) (imgRatio * actualHeight);
actualWidth = (int) maxWidth;
} else {
actualHeight = (int) maxHeight;
actualWidth = (int) maxWidth;
}
}
Log.d(TAG, "ActualHeight " + actualHeight);
Log.d(TAG, "ActualHidht " + actualWidth);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = ImageUtils.calculateInSampleSize(options, actualWidth, actualHeight);
options.inJustDecodeBounds = false;
options.inDither = false;
options.inPurgeable = true;
options.inInputShareable = true;
options.inTempStorage = new byte[16 * 1024];
Bitmap bmp = null;
try {
// int bytes = byteSizeOf(image);
// //or we can calculate bytes this way. Use a different value than 4 if you don't use 32bit images.
// //int bytes = b.getWidth()*b.getHeight()*4;
// ByteBuffer buffer = ByteBuffer.allocate(bytes); //Create a new buffer
// image.copyPixelsToBuffer(buffer); //Move the byte data to the buffer
// byte[] array = buffer.array(); //Get the underlying array containing the data.
// bmp = BitmapFactory.decodeByteArray(array, 0, array.length, options);
ByteArrayOutputStream blob = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.PNG, 0 /*ignored for PNG*/, blob);
byte[] bitmapdata = blob.toByteArray();
bmp = BitmapFactory.decodeByteArray(bitmapdata , 0, bitmapdata.length);
} catch (OutOfMemoryError exception) {
exception.printStackTrace();
}
try {
scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888);
} catch (OutOfMemoryError exception) {
exception.printStackTrace();
}
float ratioX = actualWidth / (float) options.outWidth;
float ratioY = actualHeight / (float) options.outHeight;
float middleX = actualWidth / 2.0f;
float middleY = actualHeight / 2.0f;
Matrix scaleMatrix = new Matrix();
scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);
Canvas canvas = new Canvas(scaledBitmap);
canvas.setMatrix(scaleMatrix);
canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));
// ExifInterface exif;
// try {
//// exif = new ExifInterface(imagePath);
//// int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
//// Matrix matrix = new Matrix();
//// if (orientation == 6) {
//// matrix.postRotate(90);
//// } else if (orientation == 3) {
//// matrix.postRotate(180);
//// } else if (orientation == 8) {
//// matrix.postRotate(270);
//// }
//
// } catch (IOException e) {
// e.printStackTrace();
// }
scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), null, true);
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 85, fos);
return true;
}
public static void compressImage(String imagePath, FileOutputStream fos) {
Bitmap scaledBitmap = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bmp = BitmapFactory.decodeFile(imagePath, options);
int actualHeight = options.outHeight;
int actualWidth = options.outWidth;
float imgRatio = (float) actualWidth / (float) actualHeight;
float maxRatio = maxWidth / maxHeight;
if (actualHeight > maxHeight || actualWidth > maxWidth) {
if (imgRatio < maxRatio) {
imgRatio = maxHeight / actualHeight;
actualWidth = (int) (imgRatio * actualWidth);
actualHeight = (int) maxHeight;
} else if (imgRatio > maxRatio) {
imgRatio = maxWidth / actualWidth;
actualHeight = (int) (imgRatio * actualHeight);
actualWidth = (int) maxWidth;
} else {
actualHeight = (int) maxHeight;
actualWidth = (int) maxWidth;
}
}
options.inSampleSize = ImageUtils.calculateInSampleSize(options, actualWidth, actualHeight);
options.inJustDecodeBounds = false;
options.inDither = false;
options.inPurgeable = true;
options.inInputShareable = true;
options.inTempStorage = new byte[16 * 1024];
try {
bmp = BitmapFactory.decodeFile(imagePath, options);
} catch (OutOfMemoryError exception) {
exception.printStackTrace();
}
try {
scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888);
} catch (OutOfMemoryError exception) {
exception.printStackTrace();
}
float ratioX = actualWidth / (float) options.outWidth;
float ratioY = actualHeight / (float) options.outHeight;
float middleX = actualWidth / 2.0f;
float middleY = actualHeight / 2.0f;
Matrix scaleMatrix = new Matrix();
scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);
Canvas canvas = new Canvas(scaledBitmap);
canvas.setMatrix(scaleMatrix);
canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));
ExifInterface exif;
try {
exif = new ExifInterface(imagePath);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
Matrix matrix = new Matrix();
if (orientation == 6) {
matrix.postRotate(90);
} else if (orientation == 3) {
matrix.postRotate(180);
} else if (orientation == 8) {
matrix.postRotate(270);
}
scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
} catch (IOException e) {
e.printStackTrace();
}
//ByteArrayOutputStream out = new ByteArrayOutputStream();
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 85, fos);
}
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int heightRatio = Math.round((float) height / (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
final float totalPixels = width * height;
final float totalReqPixelsCap = reqWidth * reqHeight * 2;
while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
inSampleSize++;
}
return inSampleSize;
}
static protected int byteSizeOf(Bitmap data) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1) {
return data.getRowBytes() * data.getHeight();
} else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
return data.getByteCount();
} else {
return data.getAllocationByteCount();
}
}
}
/**
* reduces the size of the image
* @param image
* @param maxSize
* @return
*/
public Bitmap getResizedBitmap(Bitmap image, int maxSize) {
int width = image.getWidth();
int height = image.getHeight();
float bitmapRatio = (float)width / (float) height;
if (bitmapRatio > 0) {
width = maxSize;
height = (int) (width / bitmapRatio);
} else {
height = maxSize;
width = (int) (height * bitmapRatio);
}
return Bitmap.createScaledBitmap(image, width, height, true);
}
private void setVideoViewRatio(VideoView vv, int maxSize, int cWidth, int cHeight){
int width = cWidth;
int height = cHeight;
float ratio = (float)cWidth / (float) height;
if (ratio > 0) {
width = maxSize;
height = (int) (width / ratio);
} else {
height = maxSize;
width = (int) (height * ratio);
}
vv.setMinimumWidth(width);
vv.setMinimumHeight(height);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.