撤消/重做整个图像的调整(Android)

时间:2013-04-03 19:28:30

标签: android image-processing processing undo

注意:

请耐心等待,这个(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多分钟,所以我现在放弃了。

问题:

  1. 为此目的,是否有更快的方式来编写/读取数据?

  2. ......或者我应该回到最初的想法并尝试尽可能地解决它的问题?

  3. 还有其他建议吗?

  4. 更新

    我想出了这种方法来编写原始数据:

    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毫秒才能完成。有没有优化的想法?

1 个答案:

答案 0 :(得分:0)

我建议找出Android“暂存磁盘”区域是什么,并将图像作为磁贴处理,将它们缓存在该暂存磁盘上。这可能比直接内存使用慢一点,但这意味着您可以在不受内存限制的情况下进行图像编辑,并且(如果Android的SDK具有合理的API),将磁贴写入完整文件不应该花费太长时间。也就是说,你已经从“处理”转移到普通Java了,所以问题不再是关于处理......我的答案可能不如那些熟悉Android SDK的人