Jak programowo zmienić kontrast bitmapy w Androidzie?
Chcę programowo zmienić kontrast bitmapy. Do tej pory próbowałem tego.
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;
}
Ale to nie działa zgodnie z oczekiwaniami. Proszę, pomóż mi w tym lub podaj inne rozwiązanie, aby to osiągnąć. Z góry dzięki.
8 answers
Spróbuj tego. Twój kod nie zadziałał, ponieważ tworzysz tylko mutowalną bitmapę i nie kopiujesz obrazu bitmapy źródłowej do mutowalnej, jeśli się nie mylę.
Mam nadzieję, że pomoże:)
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;
}
Oto pełna Metoda:
/**
*
* @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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-26 17:36:27
Oto implementacja Renderscript (z przykładowych projektów 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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-03 12:14:06
Możemy użyć seek bar
do regulacji kontrastu.
Główna aktywność.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>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-23 11:10:10
Po prostu miałem ten sam problem i skończyło się na użyciu Color Matrix
, że Rusłan Janczyszyn opisuje. Musiałem automatycznie dostosować jasność w zależności od obrazu, więc użyłem BoofCV do stworzenia histogramu ze skalowanej wersji obrazu - Przetworzenie całego obrazu zajęło dużo czasu. Następnie przeanalizowałem histogram-spojrzałem na to, co było najciemniejsze i najjaśniejsze kolory, a następnie stworzyłem matrycę kolorów, która przekształca kolory tak, że najciemniejsze kolory to 0, a najjaśniejsze kolory to 255. W w ten sposób nowy obraz wykorzystuje całe spektrum od ciemnego / czarnego do jasnego/białego.
Skończyłem pisząc mały post o tym, jak to zrobiłem na naszym firmowym blogu tutaj, jeśli ktoś jest zainteresowany. http://appdictive.dk/blog/projects/2016/07/26/levels_with_color_matrix/
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-23 21:16:25
Może spróbujesz tego:
Http://xjaphx.wordpress.com/2011/06/21/image-processing-contrast-image-on-the-fly/
Mam nadzieję, że to pomoże! :)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-15 08:19:39
Http://android.okhelp.cz/bitmap-set-contrast-and-brightness-android/
Spójrz na to ,to może rozwiązać twój problem
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-15 08:57:10
Założenie-ImageView służy do wyświetlania bitmapy
Zrobiłem więcej ulepszeń w odpowiedzi Rusłana
Zamiast za każdym razem zastępować bitmapę (co czyni ją powolną, jeśli używasz paska wyszukiwania) możemy pracować nad filtrem kolorów 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-jasność można również zmieniać wraz z kontrastem za pomocą tej metody
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-08 09:48:39