1

笔记:

请耐心等待,这(恕我直言)不是十几个关于在绘画/绘图场景中撤消的问题的重复。

背景:

我一直在使用 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. 还有其他建议吗?

更新:

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

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

4

1 回答 1

0

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

于 2013-04-04T20:04:18.833 回答