【问题标题】:Faster way to set a (PNG) bitmap color instead of pixel by pixel更快地设置(PNG)位图颜色而不是逐像素设置
【发布时间】:2010-11-22 22:52:32
【问题描述】:

我有一些我正在应用颜色的 png 文件。颜色根据用户选择而改变。我通过另一种方法设置的 3 个 RGB 值更改颜色。 png 文件是一个随机的形状,在形状之外是完全透明的。我不想修改透明度,只修改 RGB 值。目前,我正在逐像素设置 RGB 值(参见下面的代码)。

我开始意识到这非常慢,并且可能只是在应用程序中不够高效。有没有更好的方法可以做到这一点?

这是我目前正在做的事情。您可以看到像素阵列对于占据屏幕相当大一部分的图像来说是巨大的:

public void foo(Component component, ComponentColor compColor, int userColor) {
    int h = component.getImages().getHeight();
    int w = component.getImages().getWidth();
    mBitmap = component.getImages().createScaledBitmap(component.getImages(), w, h, true);

    int[] pixels = new int[h * w];

    //Get all the pixels from the image
    mBitmap[index].getPixels(pixels, 0, w, 0, 0, w, h);

    //Modify the pixel array to the color the user selected
    pixels = changeColor(compColor, pixels);

    //Set the image to use the new pixel array
    mBitmap[index].setPixels(pixels, 0, w, 0, 0, w, h);
}

public int[] changeColor(ComponentColor compColor, int[] pixels) {
    int red = compColor.getRed();
    int green = compColor.getGreen();
    int blue = compColor.getBlue();
    int alpha;

    for (int i=0; i < pixels.length; i++) {
        alpha = Color.alpha(pixels[i]);
        if (alpha != 0) {
            pixels[i] = Color.argb(alpha, red, green, blue);
        }
    }
    return pixels;
}

【问题讨论】:

  • 也许您可以使用带有调色板的图像?由于您对所有内容都使用一种颜色,这意味着无论如何您只能从一个输入中获得 256 种可能的像素颜色(因为 RGB 部分是相同的,只有 A 部分会有所不同)。如果您的图像有一个包含 256 种不同颜色的调色板,它们仅在 Alpha 通道的值上有所不同,那么您只需要修改调色板,而不需要修改图像数据本身。
  • 我要么不理解你,要么你并不真正理解我的问题。我要修改的每个图像都有 2 个 alpha 值,完全透明和半透明/不透明。我想修改 RGB 值并保持 alpha 值相同。也就是说,虽然我得到了调色板的概念,但 android 中没有 Palette 类。你建议我读什么?
  • @user:是的,想法是,如果您的 PNG 文件使用调色板,您不必修改像素,只需修改调色板。即使没有 SDK 支持,您也可以将 PNG 文件本身作为原始数据读取,并在通过内存流加载之前修改内存中的调色板。这不是一个非常漂亮的解决方案,但是如果您需要它并且没有人有更好的想法,它仍然可能带来性能改进。不过,这应该相对简单,因为您不必处理压缩数据;详情请参考the PNG spec

标签: java android colors


【解决方案1】:

您查看过Bitmap 中可用的功能吗? extractAlpha 之类的东西听起来可能很有用。您还可以查看在 Android 中实现此类功能的方式,看看如果它不能完全满足您的需求,您如何使其适应您的特定情况。

【讨论】:

  • Bitmap 中可能有一些东西,但从它的声音来看,extractAlpha 不会这样做,因为它没有考虑您传递方法的油漆的 RGB 值(除非它是只是无证)。可能值得一试。我试试看。
  • 我并不是说它会解决你的整个问题,只是它会很有用。如果您阅读文档,它会谈到将其与 drawCanvas 结合以填充颜色信息。
  • 哇,成功了!!!不幸的是,只有 2.2 而不是 1.6。在 1.6 上遇到奇怪的问题,但我想这是另一个问题。
【解决方案2】:

对我有用的答案是 Square 在这里写的 Transparent jpegs

他们提供了一个更快的代码 sn-p 来做这件事。我尝试了 extractAlpha 并没有用,但 Square 的解决方案可以。只需修改他们的解决方案,改为修改颜色位而不是 alpha 位。

pixels[x] = (pixels[x] & 0xFF000000) | (color & 0x00FFFFFF);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-04
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多