zoukankan      html  css  js  c++  java
  • 调整图像亮度、对比度、饱和度

    完整代码如下:
    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();
      }
      }

  • 相关阅读:
    openwrt 相关文章
    负载均衡相关文章
    Today's Progress
    Rodrigues formula is beautiful, but uneven to sine and cosine. (zz Berkeley's Page)
    Camera Calibration in detail
    Fundamental Matrix in Epipolar
    Camera Calibration's fx and fy do Cares in SLAM
    FilterEngine::apply
    FilterEngine 类解析——OpenCV图像滤波核心引擎(zz)
    gaussBlur
  • 原文地址:https://www.cnblogs.com/bigdream6/p/8384174.html
Copyright © 2011-2022 走看看