Je veux modifier par programme le contraste du bitmap. Jusqu'à présent, j'ai essayé cela.
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;
}
Mais cela ne fonctionne pas comme prévu. S'il vous plaît, aidez-moi ou fournissez toute autre solution pour y parvenir. Merci d'avance.
Essaye ça. Votre code n'a pas fonctionné parce que vous créez uniquement un bitmap mutable et n'avez pas copié l'image du bitmap source vers le mutable si je ne me trompe pas.
J'espère que ça aide :)
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;
}
Voici la méthode complète:
/**
*
* @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;
}
On peut utiliser seek bar
pour régler le contraste.
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>
Voici une implémentation de Renderscript ( à partir des exemples de projets Gradle )
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;
}
J'ai juste eu le même problème et j'ai fini par utiliser le Color Matrix
que Ruslan Yanchyshyn décrit. J'avais besoin d'ajuster automatiquement la luminosité en fonction de l'image, j'ai donc utilisé BoofCV pour créer un histogramme à partir d'une version mise à l'échelle de l'image - Il a fallu beaucoup de temps pour traiter l'image entière. Ensuite, j'ai analysé l'histogramme - j'ai regardé quelles étaient les couleurs les plus sombres et les plus lumineuses, puis j'ai créé une matrice de couleurs qui transforme les couleurs de sorte que les couleurs les plus sombres sont 0 et les couleurs les plus brillantes sont 255. De cette façon, la nouvelle image utilise tout le spectre de l'obscurité/noir à clair/blanc maintenant.
J'ai fini par écrire un petit article sur la façon dont je l'ai fait sur le blog de notre entreprise ici si quelqu'un est intéressé. http://appdictive.dk/blog/projects/2016/07/26/levels_with_color_matrix/
http://Android.okhelp.cz/bitmap-set-contrast-and-brightness-Android/
jetez un oeil à cela, cela pourrait résoudre votre problème
Vous pouvez peut-être essayer celui-ci:
http://xjaphx.wordpress.com/2011/06/21/image-processing-contrast-image-on-the-fly/
J'espère que cela pourra aider! :)
Hypothèse - ImageView est utilisé pour afficher le bitmap
J'ai fait une amélioration supplémentaire dans la réponse du Ruslan
Au lieu de remplacer bitmap à chaque fois (ce qui le rend lent si vous utilisez la barre de recherche), nous pouvons travailler sur le Filtre couleur de l'ImageView.
float contrast;
float brightness = 0;
ImageView imageView;
// SeekBar ranges from 0 to 90
// contrast ranges from 1 to 10
mSeekBarContrast.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
contrast = (float) (i + 10) / 10;
// Changing the contrast of the bitmap
imageView.setColorFilter(getContrastBrightnessFilter(contrast,brightness));
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
ColorMatrixColorFilter getContrastBrightnessFilter(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
});
return new ColorMatrixColorFilter(cm);
}
P.S - La luminosité peut également être modifiée avec le contraste en utilisant cette méthode