2012-10-15 42 views
15

我想以編程方式更改位圖的對比度。直到現在我已經試過了。如何以編程方式更改android中位圖的對比度?

private Bitmap adjustedContrast(Bitmap src, double value) 
    { 
     // image size 
     int width = src.getWidth(); 
     int height = src.getHeight(); 
     // create output bitmap 
     Bitmap bmOut = Bitmap.createBitmap(width, height, src.getConfig()); 
     // color information 
     int A, R, G, B; 
     int pixel; 
     // get contrast value 
     double contrast = Math.pow((100 + value)/100, 2); 

     // scan through all pixels 
     for(int x = 0; x < width; ++x) { 
      for(int y = 0; y < height; ++y) { 
       // get pixel color 
       pixel = src.getPixel(x, y); 
       A = Color.alpha(pixel); 
       // apply filter contrast for every channel R, G, B 
       R = Color.red(pixel); 
       R = (int)(((((R/255.0) - 0.5) * contrast) + 0.5) * 255.0); 
       if(R < 0) { R = 0; } 
       else if(R > 255) { R = 255; } 

       G = Color.green(pixel); 
       G = (int)(((((G/255.0) - 0.5) * contrast) + 0.5) * 255.0); 
       if(G < 0) { G = 0; } 
       else if(G > 255) { G = 255; } 

       B = Color.blue(pixel); 
       B = (int)(((((B/255.0) - 0.5) * contrast) + 0.5) * 255.0); 
       if(B < 0) { B = 0; } 
       else if(B > 255) { B = 255; } 

       // set new pixel color to output bitmap 
       bmOut.setPixel(x, y, Color.argb(A, R, G, B)); 
      } 
     } 
     return bmOut; 
    } 

但是,這並不像預期的那樣工作。請幫助我或提供任何其他解決方案來實現此目標。提前致謝。

+0

預期什麼不起作用?請詳細說明什麼工作和什麼不工作。 – devsnd

回答

16

試試這個。你的代碼不工作,因爲你只創建一個可變的位圖,並沒有將源位圖的圖像複製到可變的位圖,如果我沒有錯。

希望它能幫助:)

private Bitmap adjustedContrast(Bitmap src, double value) 
{ 
    // image size 
    int width = src.getWidth(); 
    int height = src.getHeight(); 
    // create output bitmap 

    // create a mutable empty bitmap 
    Bitmap bmOut = Bitmap.createBitmap(width, height, src.getConfig()); 

    // create a canvas so that we can draw the bmOut Bitmap from source bitmap 
    Canvas c = new Canvas(); 
    c.setBitmap(bmOut); 

    // draw bitmap to bmOut from src bitmap so we can modify it 
    c.drawBitmap(src, 0, 0, new Paint(Color.BLACK)); 


    // color information 
    int A, R, G, B; 
    int pixel; 
    // get contrast value 
    double contrast = Math.pow((100 + value)/100, 2); 

    // scan through all pixels 
    for(int x = 0; x < width; ++x) { 
     for(int y = 0; y < height; ++y) { 
      // get pixel color 
      pixel = src.getPixel(x, y); 
      A = Color.alpha(pixel); 
      // apply filter contrast for every channel R, G, B 
      R = Color.red(pixel); 
      R = (int)(((((R/255.0) - 0.5) * contrast) + 0.5) * 255.0); 
      if(R < 0) { R = 0; } 
      else if(R > 255) { R = 255; } 

      G = Color.green(pixel); 
      G = (int)(((((G/255.0) - 0.5) * contrast) + 0.5) * 255.0); 
      if(G < 0) { G = 0; } 
      else if(G > 255) { G = 255; } 

      B = Color.blue(pixel); 
      B = (int)(((((B/255.0) - 0.5) * contrast) + 0.5) * 255.0); 
      if(B < 0) { B = 0; } 
      else if(B > 255) { B = 255; } 

      // set new pixel color to output bitmap 
      bmOut.setPixel(x, y, Color.argb(A, R, G, B)); 
     } 
    } 
    return bmOut; 
} 
+0

謝謝,但我不認爲我們在這裏需要'Canvas' - 我們直接寫入位圖'bmOut'。 –

1
+0

感謝您的回覆。我試過這個。但是,這段代碼僅適用於畫布,我無法從畫布中檢索更改後的圖像。那麼有沒有其他辦法呢。 –

+0

我編輯了上面的鏈接。我希望這會對你的情況更有幫助。 :) – kdroider

+0

這是我上面給出的相同的代碼。它總是使我的圖像變得黑白,並且不會使它恢復原來的顏色。請提供任何其他信息。 –

42

下面是完整的方法:

/** 
* 
* @param bmp input bitmap 
* @param contrast 0..10 1 is default 
* @param brightness -255..255 0 is default 
* @return new bitmap 
*/ 
public static Bitmap changeBitmapContrastBrightness(Bitmap bmp, float contrast, float brightness) 
{ 
    ColorMatrix cm = new ColorMatrix(new float[] 
      { 
       contrast, 0, 0, 0, brightness, 
       0, contrast, 0, 0, brightness, 
       0, 0, contrast, 0, brightness, 
       0, 0, 0, 1, 0 
      }); 

    Bitmap ret = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig()); 

    Canvas canvas = new Canvas(ret); 

    Paint paint = new Paint(); 
    paint.setColorFilter(new ColorMatrixColorFilter(cm)); 
    canvas.drawBitmap(bmp, 0, 0, paint); 

    return ret; 
} 
+1

這是迄今爲止我找到的最快解決方案。可能只有一個基於渲染的渲染纔會更快...... –

+0

太棒了,這個方法在大約一秒的時間內處理了我的圖像,上面的方法花費了大約20秒。 – Gusten

+1

什麼是對比度和亮度的最大值和最小值。我使用-255 t0 255的亮度和-100到100的對比度,但是我得到了錯誤的結果。 我也嘗試使用值0作爲對比度,而一些亮度值我得到一個黑色的圖像。請幫助我。我得到這是最快的方法,但它給了我錯誤的結果,肯定我做錯了,如果有人糾正我會很好。 – mnsalim

5

這裏一個Renderscript實現(from the Gradle Example Projects

ip.rsh

#pragma version(1) 
#pragma rs java_package_name(your.app.package) 

contrast.rs

#include "ip.rsh" 

static float brightM = 0.f; 
static float brightC = 0.f; 

void setBright(float v) { 
    brightM = pow(2.f, v/100.f); 
    brightC = 127.f - brightM * 127.f; 
} 

void contrast(const uchar4 *in, uchar4 *out) 
{ 
#if 0 
    out->r = rsClamp((int)(brightM * in->r + brightC), 0, 255); 
    out->g = rsClamp((int)(brightM * in->g + brightC), 0, 255); 
    out->b = rsClamp((int)(brightM * in->b + brightC), 0, 255); 
#else 
    float3 v = convert_float3(in->rgb) * brightM + brightC; 
    out->rgb = convert_uchar3(clamp(v, 0.f, 255.f)); 
#endif 
} 

的Java

private Bitmap changeBrightness(Bitmap original RenderScript rs) { 
    Allocation input = Allocation.createFromBitmap(rs, original); 
    final Allocation output = Allocation.createTyped(rs, input.getType()); 
    ScriptC_contrast mScript = new ScriptC_contrast(rs); 
    mScript.invoke_setBright(50.f); 
    mScript.forEach_contrast(input, output); 
    output.copyTo(original); 
    return original; 
} 
+0

您能發佈更多完整的示例嗎? –

+0

該示例是相當完整的,爲整合它看到鏈接,頁面底部完整的項目 – for3st

+0

反正你可以直接鏈接到完整的項目? :)我發現只有一個鏈接,它不可用 –

2

我有同樣的問題,並最終使用Color Matrix是魯斯蘭Yanchyshyn描述。我需要根據圖像自動調整亮度,所以我使用BoofCV從圖像的縮放版本創建直方圖 - 處理整個圖像花了很長時間。然後我分析了直方圖 - 查看最黑和最亮的顏色,然後創建一個顏色矩陣,將顏色變換爲最深的顏色爲0,最亮的顏色爲255.以這種方式,新圖像使用黑暗的全部光譜/黑色現在點亮/白色。

如果有人有興趣,我寫了一篇關於如何在我們公司的博客上撰寫的小貼子。 http://appdictive.dk/blog/projects/2016/07/26/levels_with_color_matrix/

4

我們可以使用seek bar來調整對比度。

enter image description here

MainActivity.java:

import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.ColorMatrix; 
import android.graphics.ColorMatrixColorFilter; 
import android.graphics.Paint; 
import android.os.Bundle; 
import android.support.v7.app.AppCompatActivity; 
import android.widget.ImageView; 
import android.widget.SeekBar; 
import android.widget.TextView; 

public class MainActivity extends AppCompatActivity { 

    ImageView imageView; 
    SeekBar seekbar; 
    TextView textView; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     imageView = (ImageView) findViewById(R.id.image); 
     textView = (TextView) findViewById(R.id.label); 

     seekbar = (SeekBar) findViewById(R.id.seekbar); 
     seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { 
      @Override 
      public void onProgressChanged(SeekBar seekBar, int progress, boolean b) { 
       imageView.setImageBitmap(changeBitmapContrastBrightness(BitmapFactory.decodeResource(getResources(), R.drawable.lhota), (float) progress/100f, 1)); 
       textView.setText("Contrast: "+(float) progress/100f); 
      } 

      @Override 
      public void onStartTrackingTouch(SeekBar seekBar) {} 

      @Override 
      public void onStopTrackingTouch(SeekBar seekBar) {} 
     }); 

     seekbar.setMax(200); 
     seekbar.setProgress(100); 
    } 

    public static Bitmap changeBitmapContrastBrightness(Bitmap bmp, float contrast, float brightness) { 
     ColorMatrix cm = new ColorMatrix(new float[] 
       { 
         contrast, 0, 0, 0, brightness, 
         0, contrast, 0, 0, brightness, 
         0, 0, contrast, 0, brightness, 
         0, 0, 0, 1, 0 
       }); 

     Bitmap ret = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig()); 

     Canvas canvas = new Canvas(ret); 

     Paint paint = new Paint(); 
     paint.setColorFilter(new ColorMatrixColorFilter(cm)); 
     canvas.drawBitmap(bmp, 0, 0, paint); 

     return ret; 
    } 
} 

activity_main.java:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 

    <ImageView 
     android:id="@+id/image" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" /> 

    <TextView 
     android:id="@+id/label" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:padding="8dp" 
     android:textAppearance="@android:style/TextAppearance.Holo.Medium" /> 

    <SeekBar 
     android:id="@+id/seekbar" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" /> 

</LinearLayout> 
+0

鏈接不再工作。 – Micer

+1

@Micer沒問題。我已經發布了所有的代碼 – Steve

相關問題