如何更改图像的亮度

我的问题:我希望能够改变资源图像的亮度,并将其三个实例作为ImageIcons。 一个亮度为50%(如此暗),另一个亮度为75%(亮度稍高),最后另一个亮度为100%(与原始图像相同)。 我也想保持透明度。

我尝试了什么:我已经四处搜索,看起来最好的解决方案是使用RescaleOp ,但我无法弄明白。 我不知道scaleFactor和偏移是什么。 这是我尝试过的代码。

 public void initialize(String imageLocation, float regularBrightness, float focusedBrightness, float pressedBrightness, String borderTitle) throws IOException { BufferedImage bufferedImage = ImageIO.read(ButtonIcon.class.getResource(imageLocation)); setRegularIcon(getAlteredImageIcon(bufferedImage, regularBrightness)); setFocusedIcon(getAlteredImageIcon(bufferedImage, focusedBrightness)); setPressedIcon(getAlteredImageIcon(bufferedImage, pressedBrightness)); setTitle(borderTitle); init(); } private ImageIcon getAlteredImageIcon(BufferedImage bufferedImage, float brightness) { RescaleOp rescaleOp = new RescaleOp(brightness, 0, null); return new ImageIcon(rescaleOp.filter(bufferedImage, null)); } 

电话会是这样的:

 seeATemplateButton.initialize("/resources/templateIcon-regular.png", 100f, 75f, 50f, "See A Template"); //I think my 100f, 75f, 50f variables need to change, but whenever I change them it behaves unexpectedly (changes colors and stuff). 

该代码会发生什么:图像显示为“隐形”我知道它就在那里,因为它位于JLabel上,上面有一个鼠标点击事件,并且工作得很好。 如果我只是跳过亮度变化部分并说setRegularIcon(new ImageIcon(Button.class.getResource(imageLocation));它工作正常,但显然它不是更暗。

我认为我需要的是:有些帮助理解offsetscaleFactorfilter方法的意思/做法,以及因此为亮度变量提供的数字。

任何帮助将不胜感激! 谢谢!

医生说:

重新缩放操作的伪代码如下:

 for each pixel from Source object { for each band/component of the pixel { dstElement = (srcElement*scaleFactor) + offset } } 

它只是每个像素的线性变换。 该转换的参数是scaleFactoroffset 。 如果您想要100%亮度,则此变换必须是标识,即dstElement = srcElement 。 设置scaleFactor = 1offset = 0就可以了。

现在假设你想让图像变暗,像你说的那样亮度为75%。 这相当于将像素值乘以0.75。 你想要: dstElement = 0.75 * srcElement 。 所以设置scaleFactor = 0.75offset = 0就可以了。 您的值的问题是它们从0到100,您需要使用0到1之间的值。

我建议用半透明的黑色书写图像。

假设您想直接在图像上书写:

 Graphics g = img.getGraphics(); float percentage = .5f; // 50% bright - change this (or set dynamically) as you feel fit int brightness = (int)(256 - 256 * percentage); g.setColor(new Color(0,0,0,brightness)); g.fillRect(0, 0, img.getWidth(), img.getHeight()); 

或者,如果您只是将图像用于显示目的,请在paintComponent方法中执行此操作。 这是一个SSCCE:

 import java.awt.*; import java.awt.image.*; import java.io.IOException; import java.net.URL; import javax.imageio.ImageIO; import javax.swing.*; public class ImageBrightener extends JPanel{ BufferedImage img; float percentage = 0.5f; public Dimension getPreferredSize(){ return new Dimension(img.getWidth(), img.getHeight()); } public ImageBrightener(){ try { img = ImageIO.read(new URL("http://sofzh.miximages.com/java/230441-thehoff_super.jpeg")); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void paintComponent(Graphics g){ super.paintComponent(g); g.drawImage(img, 0, 0, this); int brightness = (int)(256 - 256 * percentage); g.setColor(new Color(0,0,0,brightness)); g.fillRect(0, 0, getWidth(), getHeight()); } public static void main(String[] args){ final JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new ImageBrightener()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } } 

编辑

假设代码与上面相同,你可以通过搞乱光栅化器来操纵除Alpha之外的所有东西。 这是一个例子(如果使用这个例子,绘制shadedImage而不是img )。 请注意,这不会捕获RGB值大于256且小于0的边缘情况。

  img = ImageIO.read(new URL("http://sofzh.miximages.com/java/230441-thehoff_super.jpeg")); shadedImage = new BufferedImage(img.getWidth(), img.getWidth(), BufferedImage.TYPE_INT_ARGB); shadedImage.getGraphics().drawImage(img, 0, 0, this); WritableRaster wr = shadedImage.getRaster(); int[] pixel = new int[4]; for(int i = 0; i < wr.getWidth(); i++){ for(int j = 0; j < wr.getHeight(); j++){ wr.getPixel(i, j, pixel); pixel[0] = (int) (pixel[0] * percentage); pixel[1] = (int) (pixel[1] * percentage); pixel[2] = (int) (pixel[2] * percentage); wr.setPixel(i, j, pixel); } } 

还有一些研究的例子:

  • AlphaTestAlphaTest调整图像的alpha透明度,介于0和1之间,没有偏移。 巧合的是,它还将图像重新采样为四分之三大小。

  • RescaleOpTest使用固定比例并且没有偏移RescaleOpTest同样的RescaleOpTest

  • RescaleTest将图像的所有波段在0和2之间缩放,没有偏移。

如API中所述,比例和偏移分别作为线性函数的斜率和y-截距应用于每个带。

 dstElement = (srcElement*scaleFactor) + offset 

基本逻辑是取每个像素的RGB值,添加一些因子,再次设置为resulltant矩阵(缓冲图像)

  import java.io.*; import java.awt.Color; import javax.imageio.ImageIO; import java.io.*; import java.awt.image.BufferedImage; class psp{ public static void main(String a[]){ try{ File input=new File("input.jpg"); File output=new File("output1.jpg"); BufferedImage picture1 = ImageIO.read(input); // original BufferedImage picture2= new BufferedImage(picture1.getWidth(), picture1.getHeight(),BufferedImage.TYPE_INT_RGB); int width = picture1.getWidth(); int height = picture1.getHeight(); int factor=50;//chose it according to your need(keep it less than 100) for (int y = 0; y < height ; y++) {//loops for image matrix for (int x = 0; x < width ; x++) { Color c=new Color(picture1.getRGB(x,y)); //adding factor to rgb values int r=c.getRed()+factor; int b=c.getBlue()+factor; int g=c.getGreen()+factor; if (r >= 256) { r = 255; } else if (r < 0) { r = 0; } if (g >= 256) { g = 255; } else if (g < 0) { g = 0; } if (b >= 256) { b = 255; } else if (b < 0) { b = 0; } picture2.setRGB(x, y,new Color(r,g,b).getRGB()); } } ImageIO.write(picture2,"jpg",output); }catch(Exception e){ System.out.println(e); } }}