2012-10-19 37 views
9

Moje pytanie: Chcę mieć możliwość zmiany jasności obrazu zasobu i mieć trzy jego instancje jako ImageIcons. Jeden o jasności 50% (tak ciemniejszy), inny o jasności 75% (trochę jaśniejszy), a na końcu inny o jasności 100% (taki sam jak obraz oryginalny). Ja również chcę zachować przejrzystość.Jak zmienić jasność obrazu?

Co próbowałem: Szukałem i wygląda na to, że najlepszym rozwiązaniem jest użycie RescaleOp, ale po prostu nie mogę tego rozgryźć. Nie wiem, co to jest scaleFactor i offset. Oto mój kod na to, co próbowałem.

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

Wezwanie będzie coś takiego:

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). 

Co się dzieje z tym kodem: Obraz pojawi się „niewidzialne” Wiem, że to nie dlatego, że jest na JLabel ze zdarzeniem kliknięcia myszą na tym i to działa dobrze. Jeśli po prostu pominę część zmieniającą jasność i powiem setRegularIcon(new ImageIcon(Button.class.getResource(imageLocation));, to działa dobrze, ale oczywiście nie jest ciemniejsza.

Co Chyba muszę: Niektóre pomóc zrozumienie co offset, scaleFactor, a metoda filter oznaczać/zrobić, a co za tym idzie jakie numery dać zmiennej jasności.

Każda pomoc będzie bardzo ceniona! Dzięki!

+1

zobaczyć to podobne pytanie: http: // stackoverflow. com/questions/3433275/adjust-brightness-and-contrast-of-bufferedimage-in-java –

Odpowiedz

5

Doc mówi:

Kod pseudo dla Operacja zmiany skali jest następujący:

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

To tylko liniowa transformacja na każdym pikselu. Parametry dla tej transformacji to scaleFactor i offset. Jeśli chcesz uzyskać 100% jasności, transformacja musi być tożsamością, tj. dstElement = srcElement. Ustawienie scaleFactor = 1 i offset = 0 rozwiązuje problem.

Załóżmy teraz, że chcesz, aby obraz był ciemniejszy, z jasnością 75%, tak jak mówisz. To oznacza pomnożenie wartości pikseli przez 0,75. Chcesz: dstElement = 0.75 * srcElement. Tak więc ustawienie scaleFactor = 0.75 i offset = 0 powinno załatwić sprawę. Problem z twoimi wartościami polega na tym, że idą od 0 do 100, musisz użyć wartości z zakresu od 0 do 1.

+0

Dzięki za wyjaśnienie. Niestety, kiedy zmieniam swoją jasność na 1,0f, a moje przesunięcie na 0, wciąż jest niewidoczna. Jeśli zmienię moje wywołanie 'filter' na' filter (bufferedImage, bufferedImage) 'zamiast' filter (bufferedImage, null) 'to jest śmieszny niebieski kolor. Dowolny pomysł? – kentcdodds

+0

Czy są to obrazy RGB lub w skali szarości? To istotne. Sprawdź [ten link] (http://www.exampledepot.com/egs/java.awt.image/Bright.html) –

+0

To są obrazy RGB. – kentcdodds

4

Proponuję napisać obrazek nad półprzezroczystą czernią.

Zakładając chcesz pisać bezpośrednio na obrazie:

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

Lub jeśli jesteś po prostu używając do wyświetlania obrazu, czy to w sposobie paintComponent. Oto 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); 
    } 
} 

EDIT

Zakładając ten sam kod jak wyżej, można manipulować wszystko oprócz Alpha przez brudząc z rasteryzer.Oto przykład (pomaluj shadedImage zamiast img, jeśli używasz tego przykładu). Warto zauważyć, że nie złapać przypadków brzegowych wartości RGB większa niż 256 i mniej niż 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

Czy ten efekt byłby tłem, gdyby obraz był przezroczysty? Myślę, że tak. Czy nie tak? – kentcdodds

+0

@kentcdodds Touche - Byłem przy założeniu, że kiedy powiedziałeś: "Ja również chcę zachować przejrzystość". Miałeś na myśli po prostu, że nadal powinien być przezroczysty (ale ciemniejszy). Więc jeśli ma być po prostu przejrzysty, to jest inaczej. –

+0

Tak, ale twoje SSCCE działało świetnie i pomogło mi zrozumieć, co się dzieje. Chciałbym, żeby to działało na mój przypadek użycia! – kentcdodds

1

Jeszcze kilka przykładów dla studiów:

  • AlphaTest przeskalowanie tylko przezroczystości alfa z obrazka od zera do jednego bez przesunięć. Przypadkowo, to również resamkuje obraz do wielkości trzech czwartych.

  • RescaleOpTest robi to samo za pomocą stałej skali i bez przesunięć.

  • RescaleTest waga wszystkie prążki obrazu od zera do dwóch bez przesunięć.

Jak wskazano w API, wagi i przesunięcia są stosowane do każdego pasma jako nachylenia i Y -intercept, odpowiednio, w zależności liniowej.

dstElement = (srcElement*scaleFactor) + offset 
0

podstawowa logika jest przyjąć wartość RGB każdego piksela, dodać do niej czynnik, ustawić go ponownie do resulltant matrycy (buforowany obraz)

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