我正在处理 Android 中的 AR 应用程序,该应用程序利用相机输出。我正在编写一部分代码来保存三个图像文件:原始图片、屏幕覆盖图和绘制有覆盖图的合成图片(考虑到其他两个,可能是多余的)。我的相机的原始图像大小是 2592x1944。
现在我的保存操作花费的时间比我希望的要长。我正在使用 AsyncTask 保存图片,但实际保存部分归结为以下内容:
public void onPictureTaken(byte[] data, Camera camera){
Size sz = camera.getParameters().getPictureSize();
TimingLogger tl = new TimingLogger("CodeTiming", "Start Saving");
String fileName = getNameFromTime();
tl.addSplit("Start Pic Save");
// The Picture itself
ImageFile photo = new ImageFile(fileName+"_image.jpg");
photo.write(data);
tl.addSplit("Start Overlay Save");
// The overlay with blank background
Bitmap bmp = Bitmap.createBitmap(sz.width,sz.height,Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmp);
DrawStuffOnCanvas(canvas);
ImageFile overlay = new ImageFile(fileName+"_overlay.png");
overlay.write(bitmapToByteArray(bmp,Bitmap.CompressFormat.PNG));
tl.addSplit("Start Overlay Onto Pic Save");
// The picture with the overlay drawn on
Options options = new Options();
options.inDither = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap picture = BitmapFactory.decodeByteArray(data, 0, data.length, options);
picture = picture.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas2 = new Canvas(picture);
DrawStuffOnCanvas(canvas2);
ImageFile overlay2 = new ImageFile(fileName+"_combo.jpg");
overlay2.write(bitmapToByteArray(picture,Bitmap.CompressFormat.JPEG));
tl.addSplit("Start Metadata Save");
//Save picture metadata, not relevant to question
tl.addSplit("Done");
tl.dumpToLog();
}
将 Bitmap 转换为 byte[] 是通过以下方式完成的:
byte[] bitmapToByteArray(Bitmap b,Bitmap.CompressFormat fmt){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
b.compress(fmt, 100, baos);
return baos.toByteArray();
}
请注意,所有文件对象(例如 ImageFile)都是自定义的,但所需的相关信息是它们使用 FileOutputStream 处理 byte[] 的写入。这是此运行的最新时间转储。
Start Saving: begin
Start Saving: 4 ms, Start Pic Save
Start Saving: 86 ms, Start Overlay Save
Start Saving: 3576 ms, Start Overlay Onto Pic Save
Start Saving: 2066 ms, Start Metadata Save
Start Saving: 15 ms, Done
Start Saving: end, 5747 ms
有相当多的可变性,每次保存大约 5-15 秒。由于 JPEG 压缩导致锐利线条边缘出现伪影,叠加层(本质上是在屏幕上绘制的线条)目前正在保存为 PNG 格式以提高透明度。遵循 this question 的逻辑,我看到如果我将叠加层切换为 JPEG,我会将该步骤的时间缩短一半。如您所见,我确实对合成图片进行了更改(锐边已经被图像本身模糊了),这在压缩步骤上节省了大约 20 秒。
所以我的问题是这样的。我可以做些什么来节省压缩叠加层的时间,但保留 PNG 输出吗?或者,或者,我在这里做的其他事情会浪费很多时间来加快整体保存操作吗?这样我就不需要担心 PNG 与 JPEG 了。
最佳答案
- PNG 压缩比 JPEG 压缩慢得多,尤其是当您的位图大小时。
- 如果您不关心透明度,请使用 RGB_565 而不是 ARGB_8888。
关于android - Android 中的位图压缩和速度优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22620558/