web-dev-qa-db-ja.com

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;
    }

しかし、これは期待どおりに機能しません。これで私を助けるか、これを達成するための他の解決策を提供してください。前もって感謝します。

19
Sanchit Paurush

これを試して。変更可能なビットマップのみを作成し、ソースビットマップのイメージを変更可能なビットマップにコピーしていないため、コードが機能しませんでした。

それが役に立てば幸い :)

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;
}
21
user948620

ここに完全な方法があります:

/**
 * 
 * @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;
}
49

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>
6
Stephen

これが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;
}
5
patrickf

私は同じ問題を抱えていて、Color Matrix Ruslan Yanchyshynが説明しています。画像に応じて自動的に明るさを調整する必要があったので、BoofCVを使用して、スケーリングされたバージョンの画像からヒストグラムを作成しました-画像全体の処理に時間がかかりました。次に、ヒストグラムを分析しました。最も暗い色と最も明るい色を調べ、最も暗い色が0で最も明るい色が255になるように色を変換するカラーマトリックスを作成しました。このようにして、新しい画像は暗い色からのスペクトル全体を使用します/黒から明るい/白になりました。

興味のある方がいらっしゃったら、私がどのようにそれを私たちの会社のブログに書いたかについての小さな投稿をここで書きました。 http://appdictive.dk/blog/projects/2016/07/26/levels_with_color_matrix/

2
tobalr

http://Android.okhelp.cz/bitmap-set-contrast-and-brightness-Android/

これを見てください、これはあなたの問題を解決するかもしれません

1
Amit Hooda

多分あなたはこれを試すことができます:

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

お役に立てば幸いです。 :)

1
kdroider

前提-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-この方法を使用して、コントラストとともに明るさも変更できます

1
Palkesh Jain