2012-10-15 7 views
15

Desidero modificare a livello di codice il contrasto della bitmap. Fino ad ora ho provato questo.Come modificare a livello di codice il contrasto di una bitmap in 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; 
    } 

Ma questo non funziona come previsto. Per favore aiutami in questo o fornisci qualsiasi altra soluzione per raggiungere questo obiettivo. Grazie in anticipo.

+0

ciò che non funziona come previsto? si prega di elaborare più dettagliato cosa funziona e cosa non funziona. – devsnd

risposta

16

Prova questo. Il tuo codice non ha funzionato perché crei solo una bitmap mutabile e non hai copiato l'immagine della bitmap di origine su quella mutabile se non sbaglio.

Speranza che aiuta :)

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

Grazie, ma non penso che abbiamo bisogno di un 'Canvas' qui - stiamo scrivendo direttamente alla bitmap' bmOut'. –

1

Forse si può provare questo:

http://xjaphx.wordpress.com/2011/06/21/image-processing-contrast-image-on-the-fly/

Speranza che aiuta! :)

+0

Grazie per la risposta. Ho provato questo. Ma questo codice funziona solo con canvas e non riesco a recuperare l'immagine modificata dalla tela. Quindi c'è un altro modo per farlo. –

+0

Ho modificato il link sopra. Spero che sarà più utile nel tuo caso. :) – kdroider

+0

È lo stesso codice che ho dato sopra. Rende sempre la mia immagine in bianco e nero e non ritorna ai suoi colori originali. Si prega di fornire qualsiasi altro. –

42

Ecco metodo completo:

/** 
* 
* @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

Questa è la soluzione più veloce che ho trovato finora. Probabilmente solo uno script basato su render potrebbe essere più veloce ... –

+0

Impressionante, questo metodo elabora la mia immagine in circa un secondo, al di sopra del metodo sono occorsi circa 20 secondi. – Gusten

+1

qual è il valore massimo e minimo di contrasto e luminosità. Io uso -255 t0 255 per la luminosità e -100 a 100 per il contrasto, ma ottengo risultati errati. Cerco anche di usare il valore 0 per il contrasto mentre un certo valore per la luminosità ottengo un'immagine nera.Si prega di aiutarmi. Ho ottenuto questo è il metodo più veloce, ma mi dà un risultato sbagliato, sicuramente faccio qualcosa di sbagliato, sarebbe bello se qualcuno mi correggesse. – mnsalim

5

Ecco un'implementazione 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

Puoi pubblicare un esempio più completo? –

+0

l'esempio è abbastanza completo, per l'integrazione vedi il link, in fondo alla pagina con i progetti completi – for3st

+0

puoi comunque postare un link diretto al progetto completo? :) Ho trovato solo un collegamento e non è disponibile –

2

Ho appena avuto lo stesso problema e finito per usare il Color Matrix che Ruslan Yanchyshyn descrive. Avevo bisogno di regolare automaticamente la luminosità a seconda dell'immagine, quindi ho usato BoofCV per creare un istogramma da una versione ridimensionata dell'immagine - Ci è voluto molto tempo per elaborare l'intera immagine. Poi ho analizzato l'istogramma - ho osservato quali erano i colori più scuri e più brillanti e poi ho creato una matrice di colori che trasforma i colori in modo che i colori più scuri siano 0 ei colori più brillanti siano 255. In questo modo la nuova immagine utilizza l'intero spettro dal buio/nero alla luce/bianco ora.

Ha finito per scrivere un post su come l'ho fatto sul nostro blog aziendale qui se qualcuno fosse interessato. http://appdictive.dk/blog/projects/2016/07/26/levels_with_color_matrix/

4

Possiamo usare seek bar per regolare il contrasto.

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

Il link non funziona più. – Micer

+1

@Micer Nessun problema. Ho pubblicato tutti i codici – Steve

Problemi correlati