2012-04-20 81 views
3

我正在尋找以編程方式更改背景圖像(PNG)的色調。這怎麼能在Android上完成?Android:如何更改圖像的色調?

+1

檢查這個帖子http://stackoverflow.com/questions/4354939/understanding-the-use-of-colormatrix-and-colormatrixcolorfilter-to-modify -a-draw – JRaymond 2012-04-20 23:07:06

回答

2

鏈接的柱具有一些好的想法,但是用於ColorFilter的矩陣數學可以是(a)中複合矯枉過正,和(b)中所得到的顏色引入可察覺的變化。

在此處修改janin給出的解決方案 - https://stackoverflow.com/a/6222023/1303595 - 我在Photoshop's 'Color' blend mode上根據此版本。這似乎避免因PorterDuff.Mode.Multiply圖像變暗,而且運作非常良好的色彩着色去飽和/人造黑&白圖像不失大的反差。

/* 
* Going for perceptual intent, rather than strict hue-only change. 
* This variant based on Photoshop's 'Color' blending mode should look 
* better for tinting greyscale images and applying an all-over color 
* without tweaking the contrast (much) 
*  Final color = Target.Hue, Target.Saturation, Source.Luma 
* Drawback is that the back-and-forth color conversion introduces some 
* error each time. 
*/ 
public void changeHue (Bitmap bitmap, int hue, int width, int height) { 
    if (bitmap == null) { return; } 
    if ((hue < 0) || (hue > 360)) { return; } 

    int size = width * height; 
    int[] all_pixels = new int [size]; 
    int top = 0; 
    int left = 0; 
    int offset = 0; 
    int stride = width; 

    bitmap.getPixels (all_pixels, offset, stride, top, left, width, height); 

    int pixel = 0; 
    int alpha = 0; 
    float[] hsv = new float[3]; 

    for (int i=0; i < size; i++) { 
     pixel = all_pixels [i]; 
     alpha = Color.alpha (pixel); 
     Color.colorToHSV (pixel, hsv); 

     // You could specify target color including Saturation for 
     // more precise results 
     hsv [0] = hue; 
     hsv [1] = 1.0f; 

     all_pixels [i] = Color.HSVToColor (alpha, hsv); 
    } 

    bitmap.setPixels (all_pixels, offset, stride, top, left, width, height); 
} 
4

我測試了接受的答案,不幸的是它返回了錯誤的結果。我發現,從here修改這個代碼的正常工作:

// hue-range: [0, 360] -> Default = 0 
public static Bitmap hue(Bitmap bitmap, float hue) { 
    Bitmap newBitmap = bitmap.copy(bitmap.getConfig(), true); 
    final int width = newBitmap.getWidth(); 
    final int height = newBitmap.getHeight(); 
    float [] hsv = new float[3]; 

    for(int y = 0; y < height; y++){ 
     for(int x = 0; x < width; x++){ 
      int pixel = newBitmap.getPixel(x,y); 
      Color.colorToHSV(pixel,hsv); 
      hsv[0] = hue; 
      newBitmap.setPixel(x,y,Color.HSVToColor(Color.alpha(pixel),hsv)); 
     } 
    } 

    bitmap.recycle(); 
    bitmap = null; 

    return newBitmap; 
} 
+0

此代碼有效,但速度很慢。任何想法優化? – 2018-02-25 18:31:34