我在裁剪时遇到了类似的问题,在尝试了多种方法后,我发现了这个对我来说很有意义的方法。此方法仅将图像裁剪为方形,我仍在处理圆形(请随意修改代码以获得所需的形状)。
所以,首先你有你想要裁剪的位图:
Bitmap image; //you need to initialize it in your code first of course
图像信息存储在一个 int [ ] 数组中,只不过是一个包含每个像素颜色值的整数数组,从图像的左上角开始,索引为 0,到右下角结束,索引为 N . 您可以使用带有各种参数的 Bitmap.getPixels() 方法获取此数组。
我们需要方形,因此我们需要缩短边中较长的边。此外,为了保持图像居中,需要在图像的两侧进行裁剪。希望这张图片能帮助你理解我的意思。
裁剪的视觉表示。
图像中的红点代表我们需要的初始像素和最终像素,带有破折号的变量在数值上等于没有破折号的相同变量。
现在终于代码:
int imageHeight = image.getHeight(); //get original image height
int imageWidth = image.getWidth(); //get original image width
int offset = 0;
int shorterSide = imageWidth < imageHeight ? imageWidth : imageHeight;
int longerSide = imageWidth < imageHeight ? imageHeight : imageWidth;
boolean portrait = imageWidth < imageHeight ? true : false; //find out the image orientation
//number array positions to allocate for one row of the pixels (+ some blanks - explained in the Bitmap.getPixels() documentation)
int stride = shorterSide + 1;
int lengthToCrop = (longerSide - shorterSide) / 2; //number of pixel to remove from each side
//size of the array to hold the pixels (amount of pixels) + (amount of strides after every line)
int pixelArraySize = (shorterSide * shorterSide) + (shorterImageDimension * 1);
int pixels = new int[pixelArraySize];
//now fill the pixels with the selected range
image.getPixels(pixels, 0, stride, portrait ? 0 : lengthToCrop, portrait ? lengthToCrop : 0, shorterSide, shorterSide);
//save memory
image.recycle();
//create new bitmap to contain the cropped pixels
Bitmap croppedBitmap = Bitmap.createBitmap(shorterSide, shorterSide, Bitmap.Config.ARGB_4444);
croppedBitmap.setPixels(pixels, offset, 0, 0, shorterSide, shorterSide);
//I'd recommend to perform these kind of operations on worker thread
listener.imageCropped(croppedBitmap);
//Or if you like to live dangerously
return croppedBitmap;