作者:每天好心情LJH_276 | 来源:互联网 | 2023-05-23 15:15
我正在编写一个具有简单摄像头功能的应用程序。我在主要活动中拍照,然后启动一个新线程以旋转图像,添加透明水印并将其另存为.PNG。
这个程序在运行自定义rom的三星银河S3上运行良好:AOKP,Android 4.4.2。下面给出的代码执行总时间约为2秒。根据任务管理器,我的应用程序使用了大约9 Mb的内存。
当我在运行有库存(有根)的Android 4.4.2的银河S4上运行该应用程序时,执行时间超过了27秒。该应用程序根据任务管理器使用大约124 Mb的内存(太多)。有时,应用程序崩溃并抛出OutOfMemory错误,这在S3上不会发生。
这是负责将图像保存到我的SaveThread中的代码:
TimingLogger tl = new TimingLogger("MyTag", "Saving");
String name = new SimpleDateFormat("dd-MM-yyyy_HH-mm-ss")
.format(new Date());
File myNewFolder = new File(path);
myNewFolder.mkdir();
File file = new File(path, name + ".JPEG");
OutputStream imageFileOS;
// Get EXIF rotation from byte array
int rotation = getOrientation(data);
tl.addSplit("Rotation calculated");
// Convert byte array to bitmap, and watermark bitmap
Bitmap pictureObject = BitmapFactory.decodeByteArray(data, 0,
data.length);
tl.addSplit("Decoded ByteArray to Bitmap");
// Rotate bitmap image according to EXIF data
pictureObject = rotateBitmap(rotation, pictureObject);
tl.addSplit("Bitmap rotated");
// Add watermark to rotated bitmap
Bitmap waterMarkedBitmap = addWaterMarkText(pictureObject);
tl.addSplit("Bitmap watermarked");
try {
imageFileOS = new FileOutputStream(file);
waterMarkedBitmap.compress(Bitmap.CompressFormat.PNG, 100,
imageFileOS);
tl.addSplit("Bitmap compressed");
imageFileOS.flush();
imageFileOS.close();
} catch (Exception e) {
e.printStackTrace();
}
如您所见,我添加了一个计时记录器来找出花费这么长时间的时间。下面的LogCat返回结果表明,将位图压缩为.PNG需要很长时间。我认为这可能与垃圾收集器有关。我的Logcat在执行期间返回以下内容:
02-04 13:57:08.166: I/Choreographer(30003): Skipped 73 frames! The
application may be doing too much work on its main thread.
02-04 13:57:10.528: D/dalvikvm(30003): GC_FOR_ALLOC freed 552K, 19% free 24803K/30324K, paused 48ms, total 49ms
02-04 13:57:10.628: I/dalvikvm-heap(30003): Grow heap (frag case) to 76.336MB for 51121168-byte allocation
02-04 13:57:10.918: D/dalvikvm(30003): GC_FOR_ALLOC freed 4K, 7% free 74723K/80248K, paused 23ms, total 23ms
02-04 13:57:11.019: I/dalvikvm-heap(30003): Grow heap (frag case) to 125.086MB for 51121168-byte allocation
02-04 13:57:11.859: D/dalvikvm(30003): GC_FOR_ALLOC freed 49923K, 43% free 74723K/130172K, paused 25ms, total 26ms
02-04 13:57:11.869: I/dalvikvm-heap(30003): Grow heap (frag case) to 125.086MB for 51121168-byte allocation
02-04 13:57:39.967: D/MyTag(30003): Saving: begin
02-04 13:57:39.967: D/MyTag(30003): Saving: 3 ms, Rotation calculated
02-04 13:57:39.967: D/MyTag(30003): Saving: 418 ms, Decoded ByteArray to Bitmap
02-04 13:57:39.967: D/MediaScannerConnection(30003): Scanning file 7klwibgf7fvntblfd7(7KhzCbvfib7(,6()6)(*._*+6./6*(5QHFG
02-04 13:57:39.967: D/MyTag(30003): Saving: 939 ms, Bitmap rotated
02-04 13:57:39.967: D/MyTag(30003): Saving: 96 ms, Bitmap watermarked
02-04 13:57:39.967: D/MyTag(30003): Saving: 28023 ms, Bitmap compressed
02-04 13:57:39.967: D/MyTag(30003): Saving: 0 ms, Done saving
02-04 13:57:39.967: D/MyTag(30003): Saving: 8 ms, Media scanned
02-04 13:57:39.967: D/MyTag(30003): Saving: end, 29487 ms
我不确定是否相关,但LogCat行:
D/MediaScannerConnection(30003): Scanning file 7klwibgf7fvntblfd7(7KhzCbvfib7(,6()6)(*._*+6./6*(5QHFG
显然不会显示扫描文件的路径(尽管它确实可以工作)。当我将S3连接到Eclipse时,此行会显示扫描的文件路径。
我尝试更改压缩质量,但是并没有在速度或内存使用方面做出重大改变。我不知道是什么原因导致了RAM使用率和执行时间的巨大差异。是什么会导致这种差异,我该如何解决?
编辑:完整地说,这就是在银河S3上压缩的速度:
02-04 15:40:47.980: D/MyTag(25536): Saving: 6 ms, Rotation calculated
02-04 15:40:47.980: D/MyTag(25536): Saving: 53 ms, Decoded ByteArray to Bitmap
02-04 15:40:47.980: D/MyTag(25536): Saving: 94 ms, Bitmap rotated
02-04 15:40:47.980: D/MyTag(25536): Saving: 19 ms, Bitmap watermarked
02-04 15:40:47.980: D/MyTag(25536): Saving: 210 ms, Bitmap compressed
02-04 15:40:47.980: D/MyTag(25536): Saving: 0 ms, Done saving
02-04 15:40:47.980: D/MyTag(25536): Saving: 3 ms, Media scanned
02-04 15:40:47.980: D/MyTag(25536): Saving: end, 385 ms
当我在S3上使用前置摄像头拍摄照片时,压缩时间要长得多(我真的不知道为什么...):
02-04 20:24:31.245: D/MyTag(29496): Saving: begin
02-04 20:24:31.245: D/MyTag(29496): Saving: 2 ms, Rotation calculated
02-04 20:24:31.245: D/MyTag(29496): Saving: 95 ms, Decoded ByteArray to Bitmap
02-04 20:24:31.245: D/MyTag(29496): Saving: 160 ms, Bitmap rotated
02-04 20:24:31.245: D/MyTag(29496): Saving: 25 ms, Bitmap watermarked
02-04 20:24:31.245: D/MyTag(29496): Saving: 4548 ms, Bitmap compressed
02-04 20:24:31.245: D/MyTag(29496): Saving: 0 ms, Done saving
02-04 20:24:31.245: D/MyTag(29496): Saving: 3 ms, Media scanned
02-04 20:24:31.245: D/MyTag(29496): Saving: end, 4833 ms
AndroidAddic..
5
我想到了。我犯了一个非常愚蠢的错误。我正在压缩为.PNG,但另存为.JPEG,这显然是某些设备的问题。现在压缩3096x4128图像需要2秒钟,我认为这是正常的(100%)。
虽然这不能解决所有问题。该代码仍然在S4上使用超过100 Mb,并且有时仍会引发OutOfMemory错误。该代码可在S3上完美运行。
1> AndroidAddic..:
我想到了。我犯了一个非常愚蠢的错误。我正在压缩为.PNG,但另存为.JPEG,这显然是某些设备的问题。现在压缩3096x4128图像需要2秒钟,我认为这是正常的(100%)。
虽然这不能解决所有问题。该代码仍然在S4上使用超过100 Mb,并且有时仍会引发OutOfMemory错误。该代码可在S3上完美运行。