如何在android中以编程方式更改位图的对比度?

如何在android中以编程方式更改位图的对比度?,android,image-processing,bitmap,contrast,Android,Image Processing,Bitmap,Contrast,我想通过编程更改位图的对比度。到现在为止,我已经试过了 private Bitmap adjustedContrast(Bitmap src, double value) { // image size int width = src.getWidth(); int height = src.getHeight(); // create output bitmap Bitmap bmOut = Bitmap.

我想通过编程更改位图的对比度。到现在为止,我已经试过了

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;
    }
专用位图调整对比度(位图src,双值)
{
//图像大小
int width=src.getWidth();
int height=src.getHeight();
//创建输出位图
Bitmap bmOut=Bitmap.createBitmap(宽度、高度,src.getConfig());
//颜色信息
int A,R,G,B;
整数像素;
//获取对比度值
双对比度=数学功率((100+值)/100,2);
//扫描所有像素
对于(int x=0;x255){R=255;}
G=颜色。绿色(像素);
G=(int)((G/255.0)-0.5)*对比度+0.5)*255.0);
如果(G<0){G=0;}
如果(G>255){G=255;}
B=颜色。蓝色(像素);
B=(int)((B/255.0)-0.5)*对比度+0.5)*255.0);
如果(B<0){B=0;}
如果(B>255){B=255;}
//设置新像素颜色以输出位图
设置像素(x,y,Color.argb(A,R,G,B));
}
}
返回bmOut;
}

但这并不像预期的那样有效。请在这方面帮助我,或提供任何其他解决方案来实现这一点。提前谢谢。

也许你可以试试这个:


希望有帮助!:)

试试这个。你的代码不起作用,因为你只创建了一个可变位图,如果我没有弄错的话,没有将源位图的图像复制到可变位图

希望有帮助:)

专用位图调整对比度(位图src,双值)
{
//图像大小
int width=src.getWidth();
int height=src.getHeight();
//创建输出位图
//创建一个可变的空位图
Bitmap bmOut=Bitmap.createBitmap(宽度、高度,src.getConfig());
//创建画布,以便我们可以从源位图绘制bmOut位图
Canvas c=新画布();
c、 setBitmap(bmOut);
//从src位图绘制位图到bmOut,以便我们可以修改它
c、 drawBitmap(src,0,0,新油漆(颜色为黑色));
//颜色信息
int A,R,G,B;
整数像素;
//获取对比度值
双对比度=数学功率((100+值)/100,2);
//扫描所有像素
对于(int x=0;x255){R=255;}
G=颜色。绿色(像素);
G=(int)((G/255.0)-0.5)*对比度+0.5)*255.0);
如果(G<0){G=0;}
如果(G>255){G=255;}
B=颜色。蓝色(像素);
B=(int)((B/255.0)-0.5)*对比度+0.5)*255.0);
如果(B<0){B=0;}
如果(B>255){B=255;}
//设置新像素颜色以输出位图
设置像素(x,y,Color.argb(A,R,G,B));
}
}
返回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;
}

下面是一个Renderscript实现()

ip.rsh

#pragma version(1)
#pragma rs java_package_name(your.app.package)
对比度

#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
}
爪哇


我也遇到了同样的问题,最终使用了Ruslan Yanchyshyn描述的
颜色矩阵。我需要根据图像自动调整亮度,所以我使用BoofCV从缩放后的图像创建直方图——处理整个图像需要很长时间。然后我分析了柱状图-看什么是最暗和最亮的颜色,然后创建了一个颜色矩阵来变换颜色,使最暗的颜色为0,最亮的颜色为255。通过这种方式,新图像使用了从暗/黑到亮/白的整个光谱


如果有人感兴趣的话,我会在我们公司的博客上写一篇关于我是如何做到这一点的小帖子

我们可以使用
搜索栏
调整对比度

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;
    }
}
<?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>
活动\u main.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;
    }
}
<?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>

假设-ImageView用于显示位图

我对Ruslan的回答做了进一步的改进

我们可以在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-使用此方法还可以改变亮度和对比度

谢谢您的回复。我试过这个。但这段代码仅适用于画布,我无法从画布检索更改后的图像。那么还有其他方法吗?我编辑了上面的链接。我希望这对你的情况更有帮助。:)这与我上面给出的代码相同。它总是使我的图像黑白相间,不会使它恢复到原来的颜色。请提供任何其他。什么不符合预期?请详细说明哪些有效,哪些无效。这是迄今为止我找到的最快的解决方案。可能只有基于renderscript的方法会更快…太棒了,这个方法处理我的图像大约需要一秒钟,上面的方法大约需要20秒。对比度和亮度的最大和最小值是多少。我用-255到255表示亮度,用-100到100表示对比度,但我得到了错误的结果。我