调整图像亮度、对比度、饱和度

完整代码如下:
1、主要方法编写类
package chapter4;

import java.awt.image.BufferedImage;

public class BSCAdjustFilter extends AbstractBufferedImageOp {
private double brightness;
private double contrast;
private double saturation;

public double getBrightness() {
    return brightness;
}

public void setBrightness(double brightness) {
    this.brightness = brightness;
}

public double getSaturation() {
    return saturation;
}

public void setSaturation(double saturation) {
    this.saturation = saturation;
}

public double getContrast() {
    return contrast;
}

public void setContrast(double contrast) {
    this.contrast = contrast;
}
public BufferedImage filter(BufferedImage src,BufferedImage dest){
    handleParameters();//调整各系数取值范围
    int width = src.getWidth();
    int height = src.getHeight();
    if(dest == null){
        dest = creatCompatibleDestImage(src,null);
    }
    int[] inpixels = new int[width*height];
    int[] outpixels = new int[width*height];
    getRGB(src,0,0,width,height,inpixels);

    int index = 0;
    for(int row=0;row<height;row++){
        int ta = 0,tr = 0,tg = 0,tb = 0;
        for(int col=0;col<width;col++){
            index = row*width+col;
            ta = (inpixels[index] >> 24) & 0xff;
            tr = (inpixels[index] >> 16) & 0xff;
            tg = (inpixels[index] >> 8) & 0xff;
            tb = inpixels[index] & 0xff;
            //RGB转换为HSL色彩空间
            double[] hsl = rgb2Hsl(new int[]{tr,tg,tb});

            //调整饱和度
            hsl[1] = hsl[1]*saturation;
            if(hsl[1]<0.0){
                hsl[1] = 0.0;
            }
            if(hsl[1]>255.0){
                hsl[1] = 255.0;
            }

            //调整亮度
            hsl[2] = hsl[2]*brightness;
            if(hsl[2]<0.0){
                hsl[2] = 0.0;
            }
            if(hsl[2]>255.0){
                hsl[2] = 255.0;
            }
            //HSL转换为rgb空间
            int[] rgb = hsl2RGB(hsl);
            tr = clamp(rgb[0]);
            tg = clamp(rgb[1]);
            tb = clamp(rgb[2]);

            //调整对比度
            double cr = ((tr/255.0d)-0.5d)*contrast;
            double cg = ((tg/255.0d)-0.5d)*contrast;
            double cb = ((tb/255.0d)-0.5d)*contrast;
            //输出RGB值
            tr = (int)((cr+0.5f)*255.0f);
            tg = (int)((cg+0.5f)*255.0f);
            tb = (int)((cb+0.5f)*255.0f);

            outpixels[index] = (ta << 24) | (clamp(tr) << 16 ) | (clamp(tg) << 8) | clamp(tb);
        }
    }
    setRGB(dest,0,0,width,height,outpixels);
    return dest;
}
public void handleParameters(){
    contrast = (1.0+contrast/100.0);
    brightness = (1.0 +brightness/100.0);
    saturation = (1.0+saturation/100.0);
}
public int clamp(int value){
    return value>255 ? 255:((value<0) ? 0:value);
}

}
2、抽象类,集成公有类方法
package chapter4;

import java.awt.image.BufferedImage;

/**

  • Created by LENOVO on 18-1-29.
    */
    public class AbstractBufferedImageOp {
    public static final double clo60 = 1.0/60.0;
    public static final double clo255 = 1.0/255.0;
    public int tr = 0,tg = 0,tb = 0;

    public AbstractBufferedImageOp(){}
    //读取像素数据
    public int[] getRGB(BufferedImage image,int x, int y, int width, int height,int[] pixels){
    int type = image.getType();
    if(type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB){
    return (int[]) image.getRaster().getDataElements(x,y,width,height,pixels);
    }else{
    return image.getRGB(x,y,width,height,pixels,0,width);
    }
    }
    //写入像素数据
    public void setRGB(BufferedImage image,int x, int y, int width, int height, int[] pixels){
    int type = image.getType();
    if(type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB){
    image.getRaster().setDataElements(x,y,width,height,pixels);
    }else {
    image.setRGB(x,y,width,height,pixels,0,width);
    }
    }
    public BufferedImage creatCompatibleDestImage(BufferedImage src,BufferedImage dest){

     return new BufferedImage(src.getWidth(),src.getHeight(),BufferedImage.TYPE_INT_RGB);
    

    }
    //RGB色彩空间转换为HSL色彩空间
    public double[] rgb2Hsl(int[] hsl){
    double min,max,dif,sum;
    double f1,f2;
    double h,s,l;//HSL色彩空间的三个分量
    double hsl1[]={0.0,0.0,0.0};
    tr = hsl[0];
    tg = hsl[1];
    tb = hsl[2];
    min = tr;
    if(tg<min)
    min = tg;
    if(tb<min)
    min = tb;
    max = tr;
    f1 = 0.0;
    f2 = tg-tb;
    if(tg>max){
    max = tg;
    f1 = 120.0;
    f2 = tb-tr;
    }
    if(tb >max){
    max = tb;
    f1 = 240.0;
    f2 = tr-tg;
    }
    dif = max-min;
    sum = max+min;
    l =0.5sum;//亮度仅与图像的最多颜色成分和最少的颜色成分的总量有关。亮度越小,图像越趋于黑色。亮度越高图像越趋于明亮的白色。
    if(dif == 0){//最大值与最小值相同,则表示为灰色,那么s定义为0,h未定义通常也写为0
    h = 0.0;
    s = 0.0;
    } else if(l<127.5){//根据亮度l计算饱和度
    s = 255.0
    dif/sum;
    } else{
    s = 255.0dif/(510.0-sum);
    }
    h = (f1 +60.0
    f2)/dif;//计算色调h
    if(h<0.0){
    h+=360.0;
    }
    if(h>360.0){
    h-=360.0;
    }
    hsl1[0] = h;
    hsl1[1] = s;
    hsl1[2] = l;
    return hsl1;
    }
    //HSL色彩空间转换为RGB色彩空间
    public int[] hsl2RGB(double[] hsl){
    double h,s,l;//HSL色彩空间的三个分量
    h = hsl[0];
    s = hsl[1];
    l = hsl[2];
    int[] rgb1={0,0,0};//RGB数组初始化
    double v1,v2,v3,h1;
    //HSL 转换为 RGB
    if(s == 0){//表示灰色,R,G,B定义为0
    tr = (int)l;
    tg = (int)l;
    tb = (int)l;
    }else{
    if(l<127.5){
    v2 = clo255 l(255+s);
    }else{
    v2 = l+s-clo255sl;
    }
    v1 = 2*l-v2;
    v3 = v2-v1;
    h1 = h+120.0;
    if(h1>=360.0)
    h1 -=360.0;
    //计算tr
    if(h1<60){
    tr = (int)(v1 +v3 h1 clo60);
    }else if(h1<180.0){
    tr = (int)v2;
    }else if(h1<240.0){
    tr = (int)(v1+v3
    (4-h1
    clo60));
    }else{
    tr = (int)v1;
    }
    //计算tg
    h1 = h;
    if(h1<60.0){
    tg = (int)(v1 +v3 h1 clo60);
    }else if(h1 <180.0){
    tg = (int)v2;
    }else if(h1<240.0){
    tg = (int)(v1+v3
    (4-h1
    clo60));
    }else {
    tg = (int)v1;
    }
    //计算tb
    h1 = h-120.0;
    if(h1 <0.0){
    h1 += 360.0;
    }
    if(h1<60.0){
    tb = (int)(v1 +v3 h1 clo60);
    }else if(h1<180.0){
    tb = (int)v2;
    }else if(h1<240.0){
    tb = (int)(v1+v3
    (4-h1
    clo60));
    }else{
    tb = (int)v1;
    }

     }
     rgb1[0] = tr;
     rgb1[1] = tg;
     rgb1[2] = tb;
     return rgb1;
    

    }
    }
    3、图像面板类
    package chapter4;

import javax.swing.;
import java.awt.
;
import java.awt.image.BufferedImage;

/**

  • Created by LENOVO on 18-1-29.
    */
    public class ImageJPanel extends JPanel {
    private static final long serialVersionUID = 1L;
    private BufferedImage sourceImage;
    private BufferedImage destImage;

    public ImageJPanel(){}
    public BufferedImage getSourceImage() {
    return sourceImage;
    }

    public void setSourceImage(BufferedImage sourceImage) {
    this.sourceImage = sourceImage;
    }

    public BufferedImage getDestImage() {
    return destImage;
    }

    public void setDestImage(BufferedImage destImage) {
    this.destImage = destImage;
    }

    public void process(){
    //SepiaToneFilter filter = new SepiaToneFilter();
    //SaturationFilter filter = new SaturationFilter();
    //BrightFilter filter = new BrightFilter();
    //ContrastFilter filter = new ContrastFilter();
    // destImage = filter.filter(sourceImage,null);
    //BrightContrastSatUI bcsUI = new BrightContrastSatUI(this);
    }
    public void process(double bcs[]){
    double s = 0.0,b = 0.0,c = 0.0;
    BSCAdjustFilter filter = new BSCAdjustFilter();
    filter.setSaturation(bcs[0]);
    filter.setBrightness(bcs[1]);
    filter.setContrast(bcs[2]);

     destImage = filter.filter(sourceImage,null);
    

    }

    public void paintComponent(Graphics g){
    Graphics2D g2d = (Graphics2D) g.create();
    g2d.clearRect(0,0,this.getWidth(),this.getHeight());

     if(sourceImage != null){
         g2d.drawImage(sourceImage,0,0,sourceImage.getWidth(),sourceImage.getHeight(),null);
         if(destImage != null){
             g2d.drawImage(destImage,sourceImage.getWidth()+10,0,destImage.getWidth(),destImage.getHeight(),null);
         }
     }
    

    }

}
4、滑动窗口面板类
package chapter4;

import javax.swing.;
import java.awt.
;
import java.awt.event.ActionListener;

/**

  • Created by LENOVO on 18-1-29.
    */
    public class BrightContrastSatUI extends JDialog {
    private static final long serialVersionUID = 1L;
    private JButton okBtn;
    private JLabel bLabel;
    private JLabel cLabel;
    private JLabel sLabel;

    private JSlider bSlider;
    private JSlider cSlider;
    private JSlider sSlider;

    public BrightContrastSatUI(JFrame parent){
    super(parent,"调整图像亮度、对比度、饱和度");
    initComponent();
    }
    public void initComponent(){
    okBtn = new JButton("确定");
    bLabel = new JLabel("亮度");
    cLabel = new JLabel("对比度");
    sLabel = new JLabel("饱和度");
    bSlider = new JSlider(JSlider.HORIZONTAL,-100,100,0);//滑块最大值最小值与初始值
    bSlider.setMajorTickSpacing(40);//主刻度标记之间间隔
    bSlider.setMinorTickSpacing(10);//次刻度标记之间间隔
    bSlider.setPaintLabels(true);//确定是否绘制标签
    bSlider.setPaintTicks(true);//确定是否在滑块上绘制刻度标记
    bSlider.setPaintTrack(true);//确定是否在滑道上绘制滑道

     cSlider = new JSlider(JSlider.HORIZONTAL,-100,100,0);
     cSlider.setMajorTickSpacing(40);
     cSlider.setMinorTickSpacing(10);
     cSlider.setPaintTicks(true);
     cSlider.setPaintLabels(true);
     cSlider.setPaintTrack(true);
    
     sSlider = new JSlider(JSlider.HORIZONTAL,-100,100,0);
     sSlider.setMajorTickSpacing(40);
     sSlider.setMinorTickSpacing(10);
     sSlider.setPaintTicks(true);
     sSlider.setPaintLabels(true);
     sSlider.setPaintTrack(true);
    
     this.getContentPane().setLayout(new BorderLayout());
    
     JPanel bPanel = new JPanel();
     bPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
     bPanel.add(bLabel);
     bPanel.add(bSlider);
    
     JPanel cPanel = new JPanel();
     cPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
     cPanel.add(cLabel);
     cPanel.add(cSlider);
    
     JPanel sPanel = new JPanel();
     sPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
     sPanel.add(sLabel);
     sPanel.add(sSlider);
    
     JPanel contentPanel = new JPanel();
     contentPanel.setLayout(new GridLayout(3,1));
     contentPanel.add(bPanel);
     contentPanel.add(cPanel);
     contentPanel.add(sPanel);
    
     JPanel btnPanel = new JPanel();
     btnPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
     btnPanel.add(okBtn);
    
     this.getContentPane().add(contentPanel,BorderLayout.CENTER);
     this.getContentPane().add(btnPanel,BorderLayout.SOUTH);
     this.pack();
    

    }

    public static void centre(Window w){//调整窗口位置
    Dimension us = w.getSize();
    Dimension them = Toolkit.getDefaultToolkit().getScreenSize();
    int newX = (them.width-us.width)/2;
    int newY = (them.height-us.height)/2;
    w.setLocation(newX,newY);
    }

    public int getBright(){
    return bSlider.getValue();//返回滑块的当前亮度值
    }
    public int getContrast(){
    return cSlider.getValue();//返回滑块当前对比度值
    }
    public int getSat(){
    return sSlider.getValue();//返回滑块当前饱和度值
    }
    public void showUI(){
    centre(this);
    this.setVisible(true);
    }

    public void setActionListener(ActionListener l){
    this.okBtn.addActionListener(l);
    }
    }
    5、测试类
    package chapter4;

import javax.imageio.ImageIO;
import javax.sound.midi.SysexMessage;
import javax.swing.;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.
;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

/**

  • Created by LENOVO on 18-1-29.
    */
    public class UI_MainUI extends JFrame implements ActionListener{
    private static final long serialVersionUID = 1L;
    private static final String IMG_CMD = "选择图像...";
    private static final String PROCESS_CMD = "处理";

    private JButton imgBtn;
    private JButton processBtn;
    private ImageJPanel imageJPanel;

    private BufferedImage srcImage;
    public UI_MainUI(){
    setTitle("JFrame UI —演示");
    imgBtn = new JButton(IMG_CMD);
    processBtn = new JButton(PROCESS_CMD);

     JPanel btnJpanel = new JPanel();
     btnJpanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
     btnJpanel.add(imgBtn);
     btnJpanel.add(processBtn);
    
     imageJPanel = new ImageJPanel();
     getContentPane().setLayout(new BorderLayout());
     getContentPane().add(imageJPanel,BorderLayout.CENTER);
     getContentPane().add(btnJpanel,BorderLayout.SOUTH);
    
     setupActionListener();
    

    }

    public void setupActionListener(){
    imgBtn.addActionListener(this);
    processBtn.addActionListener(this);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
    if(SwingUtilities.isEventDispatchThread()){
    System.out.println("Event Dispatch Thred!!");
    }
    if(srcImage == null){

         try {
             JOptionPane.showMessageDialog(this,"请先选择图像源文件");
             JFileChooser chooser = new JFileChooser();
             chooser.showOpenDialog(null);
             setFileTypeFilter(chooser);
             File f = chooser.getSelectedFile();
             if(f != null){
                 srcImage = ImageIO.read(f);
                 imageJPanel.setSourceImage(srcImage);//图像面板添加图像
                 imageJPanel.repaint();
             }
         } catch (IOException e1) {
             e1.printStackTrace();
         }
         return ;
     }
     if (IMG_CMD.equals(e.getActionCommand())){
         if(srcImage == null){
    
             try {
                 JOptionPane.showMessageDialog(this,"请先选择图像源文件");
                 JFileChooser chooser = new JFileChooser();
                 chooser.showOpenDialog(null);
                 File f = chooser.getSelectedFile();
                 if(f != null){
                     srcImage = ImageIO.read(f);
                     imageJPanel.setSourceImage(srcImage);//图像面板添加图像
                     imageJPanel.repaint();
                 }
             } catch (IOException e1) {
                 e1.printStackTrace();
             }
         }
     }else if(PROCESS_CMD.equals(e.getActionCommand())){
         //如果点击“处理”按钮,则跳出调整图像饱和度,对比度,亮度窗口
    
         final BrightContrastSatUI bcsUI =  new BrightContrastSatUI(this);//调整图像饱和度,对比度,亮度窗口
         //点击“确定”按钮,触发事件
         bcsUI.setActionListener(new ActionListener() {//点击确定按钮后执行
             @Override
             public void actionPerformed(ActionEvent e) {
                 bcsUI.setVisible(true);
                 double s = bcsUI.getSat();
                 double b = bcsUI.getBright();
                 double c = bcsUI.getContrast();
                 bcsUI.dispose();
                 imageJPanel.process(new double[]{s,b,c});
                 imageJPanel.repaint();
                 //System.out.print("das");
             }
         });
        bcsUI.showUI();
     }
    

    }
    public void setFileTypeFilter(JFileChooser chooser){
    FileNameExtensionFilter filter = new FileNameExtensionFilter("JPG & PNG Images","jpg","png");
    chooser.setFileFilter(filter);
    }
    public void openView(){
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setPreferredSize(new Dimension(800,600));
    pack();
    setVisible(true);
    }
    public static void main(String args[]){
    UI_MainUI ui = new UI_MainUI();
    ui.openView();
    }
    }

原文地址:https://www.cnblogs.com/bigdream6/p/8384174.html