2017-11-30 6 views
0

Ich habe ein Programm geschrieben, um Bilder zu ändern.Manchmal, aber konsistent, zu einem BufferedImage zeichnen, liefert falsche Farben

Zuerst habe ich das Bild, und erhalten ihre Zeichnung Kontext wie folgt aus:

BufferedImage image; 
try { 
    image = ImageIO.read(inputFile); 
} catch (IOException ioe) { /* exception handling ... */ } 

Graphics g = image.createGraphics(); 

Und dann ändern ich das Bild wie folgt aus:

for (int x = 0; x < image.getWidth(); x++) { 
    for (int y = 0; y < image.getHeight(); y++) { 
     g.setColor(/* calculate color ... */); 
     g.fillRect(x, y, 1, 1); 
    } 
} 

Nachdem ich fertig habe das Bild modifizierende Ich speichere das Bild so:

try { 
    ImageIO.write(image, "PNG", save.getSelectedFile()); 
} catch (IOException ioe) { /* exception handling ... */ } 

Jetzt die meiste Zeit das funktioniert gut.

Allerdings, wenn ich versuchte, Umfärbung diese Textur

enter image description here

dieser

enter image description here

bekomme ich diese statt:

enter image description here

Innerhalb des Debuggers ist die Farbe des Graphics jedoch der Rosaton, den ich möchte.

Die Kommentare scheinen zu suggerieren, dass das Bild, das der Benutzer öffnet, einige Farbbeschränkungen hat, und da ich zu dem gleichen Bild lese, von dem ich lese, muss mein Programm diese Einschränkungen einhalten. Das Beispielbild scheint ziemlich Graustufen-y zu sein, und anscheinend ist seine Bittiefe 8 Bit. Vielleicht wird das Pink, das ich darauf zeichne, in Graustufen umgewandelt, weil das Bild 8-Bit bleiben muss?

+1

Jede Möglichkeit, ein Setup (d. H. [MCVE] und Beispielbild) zur Verfügung zu stellen, wo es möglich ist, dies zu reproduzieren? – Marco13

+2

Das Farbmodell unterstützt möglicherweise nicht die Farben, die Sie verwenden – MadProgrammer

+0

@ Marco13 Ich habe ein Beispiel zu meiner Frage hinzugefügt. – JoFelix

Antwort

0

Wie in den Kommentaren vorgeschlagen, ist das Hauptproblem hier in der Tat das falsche Farbmodell. Wenn Sie das Originalbild laden, und einige Informationen über sie drucken ...

BufferedImage image = ImageIO.read(
    new URL("https://i.stack.imgur.com/pSUFR.png")); 
System.out.println(image); 

wird es sagen

[email protected]: type = 13 IndexColorModel: #pixelBits = 8 numComponents = 3 color space = [email protected] transparency = 1 transIndex = -1 has alpha = false isAlphaPre = false ByteInterleavedRaster: width = 128 height = 128 #numDataElements 1 dataOff[0] = 0 

Die IndexColorModel nicht unbedingt alle Farben nicht unterstützen, sondern nur einen Teil von ihnen. (Grundsätzlich unterstützt das Bild nur die Farben, die es "benötigt", was eine kompaktere Speicherung ermöglicht).

Die Lösung hier besteht darin, das Bild in ein Bild mit dem entsprechenden Farbmodell zu konvertieren. Eine generische Methode dafür wird im folgenden Beispiel gezeigt:

import java.awt.Color; 
import java.awt.Graphics2D; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import java.net.URL; 

import javax.imageio.ImageIO; 

public class ImageColors 
{ 
    public static void main(String[] args) throws IOException 
    { 
     BufferedImage image = ImageIO.read(
      new URL("https://i.stack.imgur.com/pSUFR.png")); 

     // This will show that the image has an IndexColorModel. 
     // This does not necessarily support all colors. 
     System.out.println(image); 

     // Convert the image to a generic ARGB image 
     image = convertToARGB(image); 

     // Now, the image has a DirectColorModel, supporting all colors 
     System.out.println(image); 

     Graphics2D g = image.createGraphics(); 
     g.setColor(Color.PINK); 
     g.fillRect(50, 50, 50, 50); 
     g.dispose(); 

     ImageIO.write(image, "PNG", new File("RightColors.png")); 
    } 

    public static BufferedImage convertToARGB(BufferedImage image) 
    { 
     BufferedImage newImage = new BufferedImage(
      image.getWidth(), image.getHeight(), 
      BufferedImage.TYPE_INT_ARGB); 
     Graphics2D g = newImage.createGraphics(); 
     g.drawImage(image, 0, 0, null); 
     g.dispose(); 
     return newImage; 
    }  
} 
Verwandte Themen