【问题标题】:Invert certain colors in a bitmap (Android)反转位图中的某些颜色 (Android)
【发布时间】:2015-01-13 07:36:43
【问题描述】:

欢迎回答我在 stackoverflow.com 上的第一个问题 :)
我正在尝试在 Android 应用中反转位图的特定颜色。
这个想法是为儿童故事提供夜间模式阅读。
故事页面色彩丰富,包括文字..

当我以正常模式加载图像时;它将按原样显示。
但是当用户激活夜间模式时(在阅读过程中按下按钮)我想反转图像的颜色。
但不是所有颜色,只有任何黑色像素要反转变为白色,,, 并保持其他颜色不变,,,,

下面是我想要做的一个插图(上半部分是反转所有颜色,,,我想实现下半部分的插图): 我用了下面的代码,,,但是抗锯齿的黑色像素仍然没有很好地反转!!

//Code snipet 
Bitmap copy = myBitmap.copy(myBitmap.getConfig(), true);
int length = copy.getWidth() * copy.getHeight();
int[] array = new int[length];
copy.getPixels(array,0,copy.getWidth(),0,0,copy.getWidth(),copy.getHeight());
for (int i=0;i<length-(length/10);i++){
    
    //trying to overcome text anti-aliasing
    if ( (array[i] & 0x00FFFFFF) <= 0x00222222)
    {
      array[i] = 0xffffffff;
    }
}
copy.setPixels(array,0,copy.getWidth(),0,0,copy.getWidth(),copy.getHeight());

我想要反转颜色的实际示例图像

【问题讨论】:

  • 谢谢,我已经用过这种方法了,效果很好;但它不适用于抗锯齿图形:(
    如果有使用 setColorFilter(ColorMatrixColorFilter(float[])) 的解决方案,那就完美了!

标签: android colors


【解决方案1】:

如果您确实想反转每种颜色,那么可以在运行时通过代码完成。

但是,为了性能和简单性,如果您事先知道图像是什么,最好事先在 Photoshop 等图像编辑工具中创建倒置图像。这样你就可以完全控制它们。将它们都加载到活动中,但隐藏倒置图像。

使用

view.setVisibility(View.INVISIBLE) and view.setVisibility(View.VISIBLE)

最初将可见性设置为不可见,然后在需要时将其更改为可见。

【讨论】:

  • 嗨@Alt-Cat,正如问题中提到的:我不想反转所有颜色!我只想反转任何黑色(考虑到抗锯齿)并保持其他颜色不变,我添加了一个我想要反转的图像的实际样本的新插图(激活夜间模式阅读)。 .. 我还添加了代码片段
  • 这是作为答案发布的,但它不会尝试回答问题。它可能应该是编辑、评论、另一个问题或完全删除。
【解决方案2】:

"BackBitmap" 将是您尝试转换的位图对象。

第 1 步是通过 getPixels(...) 方法将像素的所有颜色存储在一个数组中。 (这将逐行存储颜色。这对于下一步的理解至关重要)。

步骤 2:创建第二个一维数组,通过调用 getPixel(...) 将每个单独的像素存储在位图中

第 3 步:使用 if 语句“if ( (array[i] & 0x00FFFFFF) your Black颜色范围)",然后是一个简单的公式,将正图像转换为负图像,反之亦然:neg_col = 0xFFFFFF - orig_col; .: array[i] = 0xFFFFFF - array2[i];

//step 1
    int length = BackBitmap.getWidth() * BackBitmap.getHeight();
    int[] array = new int[length];
    BackBitmap.getPixels(array, 0, BackBitmap.getWidth(), 0, 0, BackBitmap.getWidth(), BackBitmap.getHeight())

//step 2   
    int[] array2 = new int[length];
    int a2 = 0;

    for(int col = 0; col < BackBitmap.getHeight(); col++){
                for (int row = 0; row < BackBitmap.getWidth();row++){
                    array2[a2] = BackBitmap.getPixel(row,col);
                    a2++;
                    }
       }

//step 3
    for (int i=0;i<length;i++){
        if ((array[i] & 0x00FFFFFF) <= 0x00222222){
           array[i] = 0xFFFFFF - array2[i];
           }
       }

//the next line is here just to "override" this Bitmap's immutamility
            BackBitmap = BackBitmap.copy(Bitmap.Config.ARGB_8888, true);

            BackBitmap.setPixels(array, 0, BackBitmap.getWidth(), 0, 0, BackBitmap.getWidth(), BackBitmap.getHeight());

希望这对正在努力将位图转换为负片的人们有所帮助。在这种情况下,请忽略 if 语句。

【讨论】:

    【解决方案3】:

    只需遍历位图的每个像素并将其颜色反转如下:

    private void inverseBitmapColors(Bitmap bitmap) {
    
        for (int i = 0; i < bitmap.getWidth(); i++) {
            for (int j = 0; j < bitmap.getHeight(); j++) {
                bitmap.setPixel(i, j, bitmap.getPixel(i, j) ^ 0x00ffffff);
            }
        }
    }
    

    ^ 是 XOR - 如果两个位中只有一个为 1,则将每个位设置为 1 我们将此操作应用于具有 0x00ffffff 值的像素颜色 那是因为位图颜色值以这种形式存储在 32 位上:

    第 1 个 8 位用于 alpha(透明度)

    红色的第 2 个 8 位

    第 3 个 8 位表示绿色

    蓝色的第 4 个 8 位

    我们需要反转颜色,所以不需要接触 alpha,所以我们应用 xor 值 0x00(值 0x00ffffff 的前 2 个数字)(二进制中的 00000000)所以 alpha 永远不会改变相反的红色绿色和蓝色我们需要得到它们的补码,所以我们对每一个都应用 xor 值 0xff (11111111)

    【讨论】:

      猜你喜欢
      • 2011-06-05
      • 1970-01-01
      • 2011-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多