注意:
请耐心等待,这个(imho)不是关于在绘画/绘画场景中要求撤消的十几个问题的重复。
背景
我一直在使用Processing for Android开发一个图像处理应用程序,现在我正在尝试实现一个简单的一步撤消/重做功能。
我的初始(撤消友好)想法是仅对下采样预览图像应用调整,保留一系列调整操作,并在保存时将它们应用于原始图像。我不得不解雇这个想法有两个原因:
某些操作需要几秒钟才能完成,如果我们有一些这样的操作,它会使已经很慢的保存过程变得非常慢。
当应用于下采样图像而不是全尺寸图像时,一些动作(例如,颜色噪声降低)产生完全不同(错误)的结果。但无论如何这是一个不那么严重的问题......
所以我决定使用存储前/后图像。
问题:
不幸的是,由于内存限制,缓存内存中的图像不是一种选择。所以我现在正在做的是将前/后图像保存到内部存储。
但这会造成绩效/质量困境:
jpeg 速度很快(即在我的Xperia Arc S上保存约500毫秒)但在两次/三次迭代后质量下降超出可接受性。
png 当然是无损的,但速度超慢(保存约7000毫秒),这使得它不切实际。
bmp 我猜可能会很快,但android不会编码bmp(我认为android的处理会将“file.bmp”保存为tiff)。
tiff 有一定程度的可接受性能(保存约1500毫秒),但android不解码tiff。
我还尝试使用此功能将原始像素数组写入文件:
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毫秒才能完成。有没有优化的想法?
答案 0 :(得分:0)
我建议找出Android“暂存磁盘”区域是什么,并将图像作为磁贴处理,将它们缓存在该暂存磁盘上。这可能比直接内存使用慢一点,但这意味着您可以在不受内存限制的情况下进行图像编辑,并且(如果Android的SDK具有合理的API),将磁贴写入完整文件不应该花费太长时间。也就是说,你已经从“处理”转移到普通Java了,所以问题不再是关于处理......我的答案可能不如那些熟悉Android SDK的人