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

  • 相关阅读:
    一、计算机网络概述
    一些早期的sftp在openssh升级到 openssh7可能闪断解法
    ssh: error while loading shared libraries: libcrypto.so.1.0.0
    PHP Warning: imagettftext(): Problem loading glyph in
    compile pcre on vs2008
    《祝总骧312经络锻炼法》
    神秘的经络
    益嗅上清汤
    鼻病 《仁术便览》
    鼻(附嚏)《医述》
  • 原文地址:https://www.cnblogs.com/bigdream6/p/8384174.html
Copyright © 2011-2022 走看看