2017-10-17 8 views
1

私は以下の問題があります:イメージの明るさを制御するにはどうすればよいですか?

イメージの明るさを制御する方法を作成したいと思います。私は前にそれをBufferedImageに変換しなければならないと思います。
画像にアルファチャンネルがあり、それをTYPE_INT_RGBで変換したい場合、アルファピクセルは黒です。しかし、それは正常に動作しますTYPE_INT_ARGB ...
画像にアルファチャンネルがなく、それをTYPE_INT_ARGBで変換すると動作しません。そして、明るさだけでなく、色も変化します。画像を明るくすると黄色になり、暗くすると青くなります。
別の方法で変換することはできますか、画像にアルファチャンネルがあるかどうかを確認することはできますか?ここで

は私のコードです:

public static Image brightnessControl(Image image, float brightness) { 

    //First I convert the Image to a BufferedImage 
    BufferedImage bi = new BufferedImage 
      (image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB); 
    Graphics bg = bi.getGraphics(); 
    bg.drawImage(image, 0, 0, null); 
    bg.dispose(); 

    //here I brighten/darken the BufferedImage 
    RescaleOp rescaleOp = new RescaleOp(brightness, 0, null); 
    rescaleOp.filter(bi, bi); 

    //I change the BufferedImage back to the Image again! 
    image = bi; 

    //Last but not least I return the Image... 
    return image; 
} 
+0

'rescaleOpの代わりに' image = rescaleOp.filter(bi、null);を試してください。filter(bi、bi); '([Javadoc](https://docs.oracle.com/javase/8/docs/api/java/awt/image/RescaleOp.html#filter-java.awt.imageを参照)。 BufferedImage-java.awt.image.BufferedImage-)))? – howlger

+0

@howlgerもし私がそうするなら、私はアルファチャンネルでイメージを明るくすることはできません。しかし、それは奇妙な色の問題を修正! – Andy

答えて

2

下記のコードを見てください。

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Image; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import javax.imageio.ImageIO; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class Test { 

    public static void main(String[] args) throws IOException { 

     Image img = ImageIO.read(new File("image.jpeg")); 

     new JFrame(){ 
      { 
       setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       setSize(800, 600); 
       setLocationRelativeTo(null); 
       add(new JPanel(){ 
        @Override 
        protected void paintComponent(Graphics g) { 

         super.paintComponent(g); 

         int imgWidth = img.getWidth(null); 
         int imgHeight = img.getHeight(null); 
         int lines = 4; 
         int columns = 6; 
         int count = 1; 

         for (int i = 0; i < lines; i++) { 
          for (int j = 0; j < columns; j++) { 
           g.drawImage(newBrightness(img, 1f/(lines*columns)*count), imgWidth * j, imgHeight * i, null); 
           count++; 
          } 
         } 
        } 
       }); 
      } 
     }.setVisible(true); 

    } 

    public static Image newBrightness(Image source, float brightnessPercentage) { 

     BufferedImage bi = new BufferedImage( 
       source.getWidth(null), 
       source.getHeight(null), 
       BufferedImage.TYPE_INT_ARGB); 

     int[] pixel = { 0, 0, 0, 0 }; 
     float[] hsbvals = { 0, 0, 0 }; 

     bi.getGraphics().drawImage(source, 0, 0, null); 

     // recalculare every pixel, changing the brightness 
     for (int i = 0; i < bi.getHeight(); i++) { 
      for (int j = 0; j < bi.getWidth(); j++) { 

       // get the pixel data 
       bi.getRaster().getPixel(j, i, pixel); 

       // converts its data to hsb to change brightness 
       Color.RGBtoHSB(pixel[0], pixel[1], pixel[2], hsbvals); 

       // create a new color with the changed brightness 
       Color c = new Color(Color.HSBtoRGB(hsbvals[0], hsbvals[1], hsbvals[2] * brightnessPercentage)); 

       // set the new pixel 
       bi.getRaster().setPixel(j, i, new int[]{ c.getRed(), c.getGreen(), c.getBlue(), pixel[3] }); 

      } 

     } 

     return bi; 

    } 

} 

イメージを読み取り、新しい明るさの新しいイメージでマトリックスを作成します。ここに私のプロフィール画像の結果があります。

enter image description here

EDIT:

今、それはあまりにもアルファをサポートしています。前のコードでは、新しいピクセルのアルファ成分は255に固定されていました。元のピクセルのアルファ成分(pixel[3])を使用するように変更しました。

enter image description here

EDIT 2:各ピクセルは、このコンポーネントは、値1を外挿した場合は0から1まで変化する輝度成分を有することになる

、画素は「奇妙」色を有することになります。元の明るさよりも明るく見えるようにしたいので、新しい明るさの値が1を外挿するかどうかを確認する必要があります。上の例でこれを行います。新しいピクセル輝度コンポーネントに計算される最大パーセンテージを制御するスライダーがあります。この値が最大値(1)を超えると、最大値が使用されます。私は今それが最終的にあなたを助けることを願っています:D

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Image; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import javax.imageio.ImageIO; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JSlider; 
import javax.swing.event.ChangeEvent; 
import javax.swing.event.ChangeListener; 

public class ChangeImageBrightnessExample2 { 

    public static void main(String[] args) throws IOException { 
     new ChangeImageBrightnessExample2().createUI(); 
    } 

    public void createUI() throws IOException { 

     Image img = ImageIO.read(new File("image.jpeg")); 

     new JFrame(){ 
      { 
       setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       setSize(800, 600); 
       setLocationRelativeTo(null); 

       CustomPanel panel = new CustomPanel(); 
       panel.setImage(img); 

       JSlider slider = new JSlider(0, 400, 100); 
       slider.setMinorTickSpacing(10); 
       slider.setMajorTickSpacing(50); 
       slider.setPaintLabels(true); 
       slider.setPaintTicks(true); 
       slider.setSnapToTicks(true); 
       slider.addChangeListener(new ChangeListener() { 
        @Override 
        public void stateChanged(ChangeEvent evt) { 
         JSlider s = ((JSlider) evt.getSource()); 
         if (s.getValueIsAdjusting()) { 
          panel.setMaximumBrightnessPercentage(s.getValue()/100f); 
          panel.repaint(); 
         } 

        } 
       }); 

       add(panel, BorderLayout.CENTER); 
       add(slider, BorderLayout.SOUTH); 

      } 
     }.setVisible(true); 

    } 

    public static Image newBrightness(Image source, float brightnessPercentage) { 

     BufferedImage bi = new BufferedImage( 
       source.getWidth(null), 
       source.getHeight(null), 
       BufferedImage.TYPE_INT_ARGB); 

     int[] pixel = { 0, 0, 0, 0 }; 
     float[] hsbvals = { 0, 0, 0 }; 

     bi.getGraphics().drawImage(source, 0, 0, null); 

     // recalculare every pixel, changing the brightness 
     for (int i = 0; i < bi.getHeight(); i++) { 
      for (int j = 0; j < bi.getWidth(); j++) { 

       // get the pixel data 
       bi.getRaster().getPixel(j, i, pixel); 

       // converts its data to hsb to change brightness 
       Color.RGBtoHSB(pixel[0], pixel[1], pixel[2], hsbvals); 

       // calculates the brightness component. 
       float newBrightness = hsbvals[2] * brightnessPercentage; 
       if (newBrightness > 1f) { 
        newBrightness = 1f; 
       } 

       // create a new color with the new brightness 
       Color c = new Color(Color.HSBtoRGB(hsbvals[0], hsbvals[1], newBrightness)); 

       // set the new pixel 
       bi.getRaster().setPixel(j, i, new int[]{ c.getRed(), c.getGreen(), c.getBlue(), pixel[3] }); 

      } 

     } 

     return bi; 

    } 

    private class CustomPanel extends JPanel { 

     private float maximumBrightnessPercentage = 1f; 
     private Image image; 

     @Override 
     protected void paintComponent(Graphics g) { 

      super.paintComponent(g); 

      int imgWidth = image.getWidth(null); 
      int imgHeight = image.getHeight(null); 
      int lines = 4; 
      int columns = 6; 
      int count = 1; 

      for (int i = 0; i < lines; i++) { 
       for (int j = 0; j < columns; j++) { 
        float newBrightness = maximumBrightnessPercentage/(lines*columns)*count; 
        g.drawImage(newBrightness(image, newBrightness), imgWidth * j, imgHeight * i, null); 
        g.drawString(String.format("%.2f%%", newBrightness*100), imgWidth * j, imgHeight * i + 10); 
        count++; 
       } 
      } 

     } 

     public void setMaximumBrightnessPercentage(float maximumBrightnessPercentage) { 
      this.maximumBrightnessPercentage = maximumBrightnessPercentage; 
     } 

     public void setImage(Image image) { 
      this.image = image; 
     } 

    } 

} 

次の画像をご覧ください。

enter image description here

私は今あなたが理解すると思います。そうでない場合は、私はあきらめます:D

+0

ありがとうございます!それは私が探しているものです! – Andy

+0

PNGファイルで試したところ、何らかの理由でアルファチャンネルが黒くなったのですが...なぜですか? – Andy

+1

@Andyこれはアルファをサポートします。 – davidbuzatto

2

あなたが使用することをBufferedImageに、引数で渡されたImageをキャストする必要がBufferedImage.getColorModel().hasAlpha();

public static Image brightnessControl(Image image, float brightness) { 
    // First I convert the Image to a BufferedImage 
    BufferedImage bi = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB); 
    Graphics bg = bi.getGraphics(); 

    if (bi.getColorModel().hasAlpha()) { // This will output true because you have just applied TYPE_INT_ARGB! 
     System.out.println("Image has got an alpha channel"); 
    } 

    bg.drawImage(image, 0, 0, null); 
    bg.dispose(); 

    // here I brighten/darken the BufferedImage 
    RescaleOp rescaleOp = new RescaleOp(brightness, 0, null); 
    rescaleOp.filter(bi, bi); 

    // I change the BufferedImage back to the Image again! 
    image = bi; 

    // Last but not least I return the Image... 
    return bi; 
} 

を使用し、BufferedImageでアルファチャンネルを確認するには方法は.getColorModel().hasAlpha()です。

関連する問題