【发布时间】:2013-03-25 15:31:12
【问题描述】:
注意:
请多多包涵,这(恕我直言)不是关于在绘画/绘图场景中撤消的十几个问题的重复。
背景:
我一直在使用 Processing for Android 开发一个图像处理应用程序,现在我正在尝试实现一个简单的一步撤消/重做功能。
我最初(撤消友好)的想法是仅将调整应用于下采样的预览图像,保留一系列调整操作,并在保存时将它们应用于原始图像。我不得不放弃这个想法有两个原因:
有些操作需要几秒钟才能完成,如果我们有一些操作,就会使本已缓慢的保存过程变得乏味地慢下来。
当应用于下采样图像而不是全尺寸图像时,某些操作(例如减少彩色噪声)会产生截然不同的(错误)结果。但无论如何,这是一个不太严重的问题......
所以我决定存储之前/之后的图像。
问题:
不幸的是,由于内存限制,无法在内存中缓冲图像。所以我现在正在做的是将之前/之后的图像保存到内部存储中。
但这会造成性能/质量两难:
jpeg 速度很快(即在我的 Xperia Arc S 上节省约 500 毫秒),但在两/三次迭代后会降低质量,超出可接受范围。
png 当然是无损的,但速度非常慢(保存时间约为 7000 毫秒),因此不切实际。
bmp 我想可能会很快,但 android 不编码 bmp(我认为 android 的处理将“file.bmp”保存为 tiff)。
tiff 的性能可以接受(约 1500 毫秒保存),但 android 不解码 tiff。
-
我还尝试使用此函数将 raw 像素数组写入文件:
void writeData(String filename, int[] data) { try { DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(openFileOutput(filename, Context.MODE_PRIVATE))); for (int i = 0; i < data.length; i++) { dos.writeInt(data[i]); } dos.close(); } catch (IOException e) { e.printStackTrace(); } }但它需要超过 2000 毫秒才能完成,所以我现在放弃了。
问题:
是否有更快的方法来为此目的写入/读取数据?
...还是应该回到最初的想法,尽可能地解决它的问题?
还有其他建议吗?
更新:
我想出了这个写原始数据的方法:
void saveRAW2(String filename) {
byte[] bytes = new byte[orig.pixels.length*3];
orig.loadPixels(); //orig = my original PImage, duh!
int index = 0;
for (int i = 0; i < bytes.length; i++) {
bytes[i++] = (byte)((orig.pixels[index] >> 16) & 0xff);
bytes[i++] = (byte)((orig.pixels[index] >> 8) & 0xff);
bytes[i] = (byte)((orig.pixels[index]) & 0xff);
index++;
}
saveBytes(filename, bytes);
}
...完成时间不到 1000 毫秒。
如果我将文件写入 SD 卡,它的运行速度会快 3 倍,但我想我不能指望在每部手机上都一样。对吧?
无论如何,我正在使用这种方法将保存的数据读回 orig.pixels:
void loadRAW(String filename) {
byte[] bytes = loadBytes(filename);
int index = 0;
int count = bytes.length/3;
for (int i = 0; i<count; i++) {
orig.pixels[i] =
0xFF000000 |
(bytes[index++] & 0xff) << 16 |
(bytes[index++] & 0xff) << 8 |
(bytes[index++] & 0xff);
}
orig.updatePixels();
}
这需要大约 1500 毫秒才能完成。有什么优化的想法吗?
【问题讨论】:
-
为什么内存是一个约束?你允许图像有多大?您是在使用平铺,还是这些幼稚的操作(即应用于整个图像)。附加说明:您使用纯 Java 作为处理应用程序的一部分,提出了一个问题,为什么您使用处理而不是使用带有处理的 Java 来处理某些绘图功能(但不是用于您的实际成像算法)
-
@Pomax,图像大约为 1600x1200,具体取决于设备(增量下采样图像直到它不抛出 OOM)。这与内存中的其他内容相结合,很容易达到旧设备的 16MB 限制。我没有使用平铺。
-
又是@Pomax!我不是真正的程序员,只有处理经验,想尝试一下 android 的处理。渐渐地,我不得不放弃大多数处理方法,并使用纯 java 来实现我的方法……但后来我走得太深,无法从头开始没有处理。 :) 无论如何,我想如果我仍然可以通过这个实现可接受的性能,为什么不完全开发应用程序?
标签: android image-processing processing undo