2012-12-11 116 views
1

我想從我的源圖像(PNG格式)中替換一些像素。但是我最終得到了一些令人困惑的結果。基本上我用黑色和白色替換特定的RGB值。這是我的代碼,替換Java2D中的圖像像素

import java.awt.Color; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.IOException; 

import javax.imageio.ImageIO; 

public class ChangePixel 
{ 
public static void main(String args[]) throws IOException 
{ 
    File file = new File(System.getProperty("user.dir"), "D4635.png"); 
    FileInputStream fis = new FileInputStream(file); 
    BufferedImage image = ImageIO.read(fis); 

    int[] replaceColors = new int[2]; 
    replaceColors[0] = Color.BLACK.getRGB(); 
    replaceColors[1] = Color.WHITE.getRGB(); 
    Color src = new Color(133, 101, 51); 
    int srcRGBvalue = src.getRGB(); 

    changeAlg2(image, srcRGBvalue, replaceColors); 
} 

private static void changeAlg2(BufferedImage image, int srcRGBvalue, int[] replaceColors) throws IOException 
{ 
    for (int width = 0; width < image.getWidth(); width++) 
    { 
     for (int height = 0; height < image.getHeight(); height++) 
     { 
      if (image.getRGB(width, height) == srcRGBvalue) 
      { 
       image.setRGB(width, height, ((width + height) % 2 == 0 ? replaceColors[0] : replaceColors[1])); 
      } 
     } 
    } 

    File file = new File(System.getProperty("user.dir"), "107.png"); 
    ImageIO.write(image, "png", file); 
} 
} 

它將我的源像素更改爲黑色和其他顏色,而不是白色。請告訴我,這裏有什麼問題。

由於這是我的第一篇文章,我無法附上自己的圖片。抱歉給你帶來不便。

編輯:我已經上傳了源和輸出圖像在一個網站。這是網址 來源:http://s20.postimage.org/d7zdt7kwt/D4635.png 輸出:http://s20.postimage.org/kdr4vntzx/107.png 預期輸出:在黑色像素之後,必須有白色像素出現。

編輯:解析的代碼按月德沃夏克建議,

import java.awt.Color; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.IOException; 

import javax.imageio.ImageIO; 

public class ChangePixel 
{ 
public static void main(String args[]) throws IOException 
{ 
    File file = new File(System.getProperty("user.dir"), "D12014.gif"); 
    FileInputStream fis = new FileInputStream(file); 
    BufferedImage image = ImageIO.read(fis); 

    Color src = new Color(223, 170, 66); 
    int srcRGBvalue = src.getRGB(); 
    int[] replaceColors = new int[2]; 
    replaceColors[0] = Color.MAGENTA.getRGB(); 
    replaceColors[1] = Color.CYAN.getRGB(); 

    changeAlg2(image, srcRGBvalue, replaceColors); 
} 

private static void changeAlg2(BufferedImage image, int srcRGBvalue, int[] replaceColors) throws IOException 
{ 
    BufferedImage image2 = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB); 
    for (int width = 0; width < image.getWidth(); width++) 
    { 
     for (int height = 0; height < image.getHeight(); height++) 
     { 
      if (image.getRGB(width, height) == srcRGBvalue) 
      { 
       image2.setRGB(width, height, ((width + height) % 2 == 0 ? replaceColors[0] : replaceColors[1])); 
      } 
      else 
      { 
       image2.setRGB(width, height, image.getRGB(width, height)); 
      } 
     } 
    } 

    File file = new File(System.getProperty("user.dir"), "110.gif"); 
    ImageIO.write(image2, "gif", file); 
} 
} 

問候 拉賈。

+0

圖像是否使用了一個托盤(不包括白色),任何機會? –

+0

嗨,簡,這是一個PNG圖像。這就是我所知道的。我不知道它是否使用調色板顏色。對不起。即使我將目標顏色替換爲綠色和紅色等其他顏色,我也只能看到綠色。第二種顏色丟失。 – Sivagururaja

+0

如果您使用白色和黑色而不是黑色和白色怎麼辦? –

回答

1

由於您正在添加原始圖像調色板中不存在的顏色,因此您嘗試設置的像素將被裁剪爲調色板中最接近的顏色。你需要設置一個新的顏色模式。要麼轉換爲24bpp RGB(真彩色),要麼使用新顏色擴展調色板。

似乎不可能修改現有的BufferedImageColorModel或分配一個新的,但您可以創建一個新的緩衝區並在那裏複製數據。使用相同的Raster創建一個新的BufferedImage也可以工作(只有在位深度不變時)。

如果你不介意,你可以隨時創建一個真彩色圖像。嘗試:

{ 
    BufferedImage old = image; 
    image = new BufferedImage(
     old.getWidth(), 
     old.getHeight(), 
     BufferedImage.TYPE_INT_RGB 
    ); 
    image.setData(old.getRaster()); 
} // old is no longer needed 

API參考:http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/image/BufferedImage.html

你可以嘗試以檢測圖像是否已經在真彩色(image.getColorModel() instanceof ???),以避免在不需要的時候複製的緩衝區。

您可以嘗試擴展現有的調色板。如果這是不可能的(沒有調色板開始或沒有足夠的空間),你必須回退到RGB。

參見:

http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/image/BufferedImage.html(getColorModel和構造採取ColorModel和類型)
http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/image/IndexColorModel.html(getMapSize所,getRGBs和相應的構造函數)

從看到你的實際的調色板,你需要某種形式的的重複數據刪除邏輯,因爲您的調色板已經是256字節 - PNG調色板的最大尺寸。請注意,您不應該使用較大的調色板保存圖像,而應該保存圖像中的顏色(特別是當您稍後要添加新顏色時)。您的原始文件可能已用2色調色板保存,可節省762個字節。

請注意,將圖像存儲爲索引而不是使用相同顏色數量的真彩色來存儲圖像並不會獲得太多收益。原因是無論如何,字節流(每個像素的調色板= 1字節,真彩色= 3或4字節/像素)無損壓縮(具有DEFLATE)。索引可以節省幾個字節(或者如果調色板很大,會丟失幾個字節),但它不會將文件大小減小到三分之一。

+0

謝謝Jan,根據您的建議,我創建了一個新的BufferedImage實例並已解決。 – Sivagururaja

+0

一月,我還有一個問題。如果索引調色板包含一些可用於添加新顏色的空間,那麼如何添加相同的顏色。 – Sivagururaja

+0

@Sivagururaja如果調色板有一些空閒空間,那麼可以預先分配空間(現有調色板大小+要添加的顏色數量),從顏色模型中提取調色板,將自己的顏色添加到最後,構建新顏色模型並在新的緩衝圖像構造函數中使用顏色模型。然後,您只需將數據複製到新的緩衝區。 –