Android 来自相机的图像用叠加层保存
Android Image from camera saved with overlay
我尝试了几种不同的方法来让它工作,但都停止了。我正在从相机中获取照片并使用叠加层保存它。
为了组合图像,我已经弄清楚了如何使用两个位图和一个 canvas 像这样:
Bitmap combined = Bitmap.createBitmap(mImage.getWidth(), mImage.getHeight(), null);
Canvas canvas = new Canvas(combined);
canvas.drawBitmap(image, new Matrix(), null);
canvas.drawBitmap(mOverlay, 0,0,null);
output = new FileOutputStream(new File(mFile.getPath(), mFileName + "(overlay).jpg" ));
output.write(bytes);
output.close();
问题是我使用的是 camera2,它 returns 是一张图片。我还没有找到将图像投射到位图的方法。我试过保存图像,然后使用 BitmapFactory 重新加载它,但经常以 OutOfMemory 异常结束。
有人有办法解决这个问题吗?
更新
Bitmap image = Bitmap.createBitmap(mImage.getWidth(),mImage.getHeight(), Bitmap.Config.ARGB_8888);
image.copyPixelsFromBuffer(mImage.getPlanes()[0].getBuffer().rewind());
我在另一个答案中偶然发现了这个问题,但我得到了一个 Buffer not large enough for pixels
异常,即使我指定的缓冲区比应有的大 8 倍也是如此。
我通过对每个步骤的大量不同的 SO 答案,自己弄清楚了如何做到这一点。考虑到我需要在我的应用程序中操作的位图数量,这是一些反复试验。
执行此操作的代码示例如下:
ByteBuffer buffer = capturedImage.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.remaining()];
try {
Bitmap imageBitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, new BitmapFactory.Options()).copy(Bitmap.Config.RGB_565, true);
Bitmap combined = Bitmap.createBitmap(imageBitmap, 0, 0, imageBitmap.getWidth(), imageBitmap.getHeight());
imageBitmap.recycle();
//overlay needs to be scaled to image size
Bitmap scaledBitmap = Bitmap.createScaledBitmap(mOverlay, imageBitmap.getWidth(), imageBitmap.getHeight(), false);
mOverlay.recycle();
Canvas canvas = new Canvas(combined);
canvas.drawBitmap(scaledBitmap, 0, 0, new Paint());
output = new FileOutputStream(new File(path));
combined.compress(Bitmap.CompressFormat.JPEG, 100, output);
output.close();
combined.recycle();
} catch (Exception ex) {
Log.d(TAG, "Unable to combine and save images. " + ex.getMessage());
}
我尝试了几种不同的方法来让它工作,但都停止了。我正在从相机中获取照片并使用叠加层保存它。
为了组合图像,我已经弄清楚了如何使用两个位图和一个 canvas 像这样:
Bitmap combined = Bitmap.createBitmap(mImage.getWidth(), mImage.getHeight(), null);
Canvas canvas = new Canvas(combined);
canvas.drawBitmap(image, new Matrix(), null);
canvas.drawBitmap(mOverlay, 0,0,null);
output = new FileOutputStream(new File(mFile.getPath(), mFileName + "(overlay).jpg" ));
output.write(bytes);
output.close();
问题是我使用的是 camera2,它 returns 是一张图片。我还没有找到将图像投射到位图的方法。我试过保存图像,然后使用 BitmapFactory 重新加载它,但经常以 OutOfMemory 异常结束。
有人有办法解决这个问题吗?
更新
Bitmap image = Bitmap.createBitmap(mImage.getWidth(),mImage.getHeight(), Bitmap.Config.ARGB_8888);
image.copyPixelsFromBuffer(mImage.getPlanes()[0].getBuffer().rewind());
我在另一个答案中偶然发现了这个问题,但我得到了一个 Buffer not large enough for pixels
异常,即使我指定的缓冲区比应有的大 8 倍也是如此。
我通过对每个步骤的大量不同的 SO 答案,自己弄清楚了如何做到这一点。考虑到我需要在我的应用程序中操作的位图数量,这是一些反复试验。
执行此操作的代码示例如下:
ByteBuffer buffer = capturedImage.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.remaining()];
try {
Bitmap imageBitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, new BitmapFactory.Options()).copy(Bitmap.Config.RGB_565, true);
Bitmap combined = Bitmap.createBitmap(imageBitmap, 0, 0, imageBitmap.getWidth(), imageBitmap.getHeight());
imageBitmap.recycle();
//overlay needs to be scaled to image size
Bitmap scaledBitmap = Bitmap.createScaledBitmap(mOverlay, imageBitmap.getWidth(), imageBitmap.getHeight(), false);
mOverlay.recycle();
Canvas canvas = new Canvas(combined);
canvas.drawBitmap(scaledBitmap, 0, 0, new Paint());
output = new FileOutputStream(new File(path));
combined.compress(Bitmap.CompressFormat.JPEG, 100, output);
output.close();
combined.recycle();
} catch (Exception ex) {
Log.d(TAG, "Unable to combine and save images. " + ex.getMessage());
}