プログラムでビットマップのコントラストを変更したい。今まで私はこれを試しました。
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;
}
しかし、これは期待どおりに機能しません。これで私を助けるか、これを達成するための他の解決策を提供してください。前もって感謝します。
これを試して。変更可能なビットマップのみを作成し、ソースビットマップのイメージを変更可能なビットマップにコピーしていないため、コードが機能しませんでした。
それが役に立てば幸い :)
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;
}
ここに完全な方法があります:
/**
*
* @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;
}
seek bar
コントラストを調整します。
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>
これがRenderscriptの実装です( Gradleサンプルプロジェクトから )
ip.rsh
#pragma version(1)
#pragma rs Java_package_name(your.app.package)
コントラスト.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;
}
私は同じ問題を抱えていて、Color Matrix
Ruslan Yanchyshynが説明しています。画像に応じて自動的に明るさを調整する必要があったので、BoofCVを使用して、スケーリングされたバージョンの画像からヒストグラムを作成しました-画像全体の処理に時間がかかりました。次に、ヒストグラムを分析しました。最も暗い色と最も明るい色を調べ、最も暗い色が0で最も明るい色が255になるように色を変換するカラーマトリックスを作成しました。このようにして、新しい画像は暗い色からのスペクトル全体を使用します/黒から明るい/白になりました。
興味のある方がいらっしゃったら、私がどのようにそれを私たちの会社のブログに書いたかについての小さな投稿をここで書きました。 http://appdictive.dk/blog/projects/2016/07/26/levels_with_color_matrix/
http://Android.okhelp.cz/bitmap-set-contrast-and-brightness-Android/
これを見てください、これはあなたの問題を解決するかもしれません
多分あなたはこれを試すことができます:
http://xjaphx.wordpress.com/2011/06/21/image-processing-contrast-image-on-the-fly/
お役に立てば幸いです。 :)
前提-ImageViewはビットマップを表示するために使用されます
ルスランの答えをさらに強化しました
bitmapを毎回置き換える代わりに(シークバーを使用していると遅くなる)、ImageViewのColor Filterで作業できます。
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);
}
PS-この方法を使用して、コントラストとともに明るさも変更できます