簡體   English   中英

Android GrayScale然后反轉顏色以解決位圖問題

[英]Android GrayScale then Invert colors for a bitmap issue

我正在向ImageView的畫布繪制一些位圖。 資源位圖是彩色的。 我想看到的結果是一個反轉的灰度位圖圖像。

這是我的方法在我的Samsung Galaxy S3(版本4.3)上可以正常使用,但在我的S3 Mini(版本4.1.2)上卻無法使用。

覆蓋的OnDraw(Canvas canvas)方法的內部:

    // Night mode color:
    Paint colorBMPPaint = new Paint();
    if (((EzPdfActivityPageView) mContext).bIsNightMode) {
        float invertMX[] = {
                0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
                0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
                0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
                0.0f, 0.0f, 1.0f, 0.0f, 0.0f
        };

        ColorMatrix invertCM = new ColorMatrix(invertMX);

        ColorMatrixColorFilter filter = new ColorMatrixColorFilter(invertCM);
        colorBMPPaint.setColorFilter(filter);
    }

    canvas.drawBitmap(bitmap,
                            new Rect(0, 0, (int)((bbox.right - bbox.left) * zoom), (int)((bbox.top - bbox.bottom) * zoom)),
                            pageDrawRect,
                            colorBMPPaint);

在S3 Mini上,我只能得到黑色位圖,為什么呢?

您確定矩陣設置正確嗎?

根據ColorMatrix文檔,您的輸入矩陣的定義如下:

4x5矩陣,用於轉換位圖的顏色和alpha分量。 矩陣可以作為單個數組傳遞,並按以下方式處理:

[a,b,c,d,e,

f,g,h,i,j,

k,l,m,n,o,

p,q,r,s,t]

當應用於顏色[R,G,B,A]時,所得顏色計算為:

R'= a R + b G + c B + d A + e;

G'= f R + g G + h B + i A + j;

B′= kR + 1G + mB + nA + o;

A'= p R + q G + r B + s A + t;

在您的矩陣中,r等於1.0f,其余均為0f。 據此,只有Alpha通道將為非零,因此黑色看起來像是預期的輸出。

相反,您可以執行以下操作:

ColorMatrix matrix = new ColorMatrix(); matrix.setSaturation(0);

順便說一句,在執行onDraw()時分配對象(如矩陣)不利於性能。 如果可以,請將分配移動到構造函數或其他地方。

更新:對於反轉部分可以申請額外的基質(無論是作為描述乘以矩陣這里 。或者只是繪制位圖的兩倍(這是低效率)的逆矩陣應該是-

ColorMatrix colorMatrix_Inverted = new ColorMatrix(new float[] { -1, 0, 0, 0, 255, 0, -1, 0, 0, 255, 0, 0, -1, 0, 255, 0, 0, 0, 1, 0});

根據@Doron Yakovlev-Golani的建議,我已經編輯了我的代碼,該代碼現在可以在兩種設備上使用:

        float invertMX[] = {
                -1.0f, 0.0f, 0.0f, 0.0f, 255f,
                0.0f, -1.0f, 0.0f, 0.0f, 255f,
                0.0f, 0.0f, -1.0f, 0.0f, 255f,
                0.0f, 0.0f, 0.0f, 1.0f, 0.0f
        };

        ColorMatrix saturationZero = new ColorMatrix();
        saturationZero.setSaturation(0);

        ColorMatrix finalCM = new ColorMatrix(saturationZero);
        ColorMatrix invertCM = new ColorMatrix(invertMX);
        finalCM.postConcat(invertCM);

        ColorMatrixColorFilter filter = new ColorMatrixColorFilter(finalCM);
        colorBMPPaint.setColorFilter(filter);

這對我有用:

for (int x = 0; x < bm.getWidth(); ++x) {
    for (int y = 0; y < bm.getHeight(); ++y) {
        int color = bm.getPixel(x, y);
        int r = Color.red(color);
        int g = Color.green(color);
        int b = Color.blue(color);
        int avg = (r + g + b) / 3;
        int newColor = Color.argb(255, 255 - avg, 255 - avg, 255 - avg);
        bm.setPixel(x, y, newColor);
    }
}

注意,位圖必須可變才能操作它,這可能會很有用。 如果不是,則可以執行以下操作來創建可變副本:

bm = bm.copy(bm.getConfig(), true);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM