[英]How to change the brightness of an Image
我的問題:我希望能夠更改資源圖像的亮度並將其三個實例作為 ImageIcons。 一個亮度為 50%(太暗),另一個亮度為 75%(稍微亮一點),最后一個亮度為 100%(與原始圖像相同)。 我也想保持透明度。
我試過什么:我四處搜索,看起來最好的解決方案是使用RescaleOp
,但我就是想不通。 我不知道 scaleFactor 和 offset 是什么意思。 這是我嘗試過的代碼。
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));
它工作得很好,但顯然它並沒有變暗。
我認為我需要的是:一些幫助理解offset
、 scaleFactor
和filter
方法的意思/作用,以及因此為亮度變量提供的數字。
任何幫助將不勝感激! 謝謝!
醫生說:
縮放操作的偽代碼如下:
for each pixel from Source object {
for each band/component of the pixel {
dstElement = (srcElement*scaleFactor) + offset
}
}
它只是每個像素的線性變換。 該轉換的參數是scaleFactor
和offset
。 如果你想要 100% 的亮度,這個變換必須是一個身份,即dstElement = srcElement
。 設置scaleFactor = 1
和offset = 0
就可以了。
現在假設你想讓圖像更暗,像你說的那樣亮度為 75%。 這相當於將像素值乘以 0.75。 你想要: dstElement = 0.75 * srcElement
。 所以設置 scaleFactor = 0.75
和offset = 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://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);
}
}
編輯
假設代碼與上面相同,您可以通過弄亂光柵化器來操縱除 Alpha 之外的所有內容。 這是一個示例(如果使用此示例,則繪制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);
}
}
再舉幾個例子供大家學習:
AlphaTest
僅在 0 和 1 之間重新調整圖像的 alpha 透明度,沒有任何偏移。 巧合的是,它還將圖像重新采樣為四分之三大小。
RescaleOpTest
使用固定比例和無偏移做同樣的事情。
RescaleTest
在 0 到 2 之間縮放圖像的所有波段,沒有偏移。
如API中所述,比例和偏移分別作為線性函數的斜率和y軸截距應用於每個波段。
dstElement = (srcElement*scaleFactor) + offset
基本邏輯是獲取每個像素的 RGB 值,向其添加一些因素,再次將其設置為結果矩陣(緩沖圖像)
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);
}
}}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.