2012-10-19 79 views
9

我的问题:我希望能够更改资源图像的亮度并将其三个实例作为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方法意味着/去做,因此什么号码给了亮度可变。

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

+1

看到类似的问题:HTTP://计算器。 com/questions/3433275/adjust-brightness-and-contrast-of-bufferedimage-in-java –

回答

5

的医生说:

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

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之间的值。

+0

感谢您的解释。不幸的是,当我将亮度更改为1.0f并将偏移量更改为0时,它仍然不可见。如果我将'filter'调用改为'filter(bufferedImage,bufferedImage)'而不是'filter(bufferedImage,null)',这是一个有趣的蓝色。任何想法? – kentcdodds

+0

这些RGB或灰度图像?这是相关的。检查[此链接](http://www.exampledepot.com/egs/java.awt.image/Bright.html) –

+0

这些是RGB图像。 – kentcdodds

4

我会建议用半透明的黑色写在图像上。

假设你想在图像上直接写:

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://media.giantbomb.com/uploads/0/1176/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); 
    } 
} 

编辑

假设与上面相同的代码,你可以通过使用光栅操作搞乱除了阿尔法的一切。以下是一个示例(如果使用此示例,则绘制shadedImage而不是img)。请注意,这不赶边缘情况的RGB值大于256且小于0

 img = ImageIO.read(new URL("http://media.giantbomb.com/uploads/0/1176/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); 
      } 
     } 
+0

如果图像具有透明度,会影响背景吗?我认为会的。不是吗? – kentcdodds

+0

@kentcdodds Touche - 当你说“我也想保持透明度”时,我的想法是假设的。你的意思是它应该仍然是透明的(但更黑)。所以如果它应该是透明的,那就不同了。 –

+0

是的,但你的SSCCE运作良好,并帮助我了解发生了什么事。希望它能用于我的用例! – kentcdodds

1

学习几个例子:

  • AlphaTest再缩放只是一个形象的Alpha透明度零和一之间没有偏移量。巧合的是,它也将图像重新采样到四分之三的大小。

  • RescaleOpTest使用固定比例和无偏移来做同样的事情。

  • RescaleTest比例尺全部 0到2之间的图像带没有偏移。

API,规模指出和偏移被分别施加到每个频带作为斜率和ÿ截距,一个线性函数的。

dstElement = (srcElement*scaleFactor) + offset 
0

基本逻辑是取各像素的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); 
    } 
    }}