2008-10-21 22 views
19

मेरे पास दो bufferedImages हैं जिन्हें मैंने पीएनजी से लोड किया है। पहले छवि में एक छवि, दूसरा अल्फा मास्क होता है।जावा में BufferedImage अल्फा मास्क सेट करें

मैं अल्फा मास्क लगाने के द्वारा, दोनों से संयुक्त छवि बनाना चाहता हूं। मेरा google-fu मुझे विफल करता है।

मुझे पता है कि छवियों को कैसे लोड/सहेजना है, मुझे केवल थोड़ी आवश्यकता है जहां मैं दो बुफर्ड इमेज से दाएं अल्फा चैनल के साथ एक बुफर्ड इमेज में जाता हूं।

+0

मैं एक सही कोड देने के लिए मेरा उत्तर संपादित (कर आप क्या अनुरोध किया!)। – PhiLho

उत्तर

9

आरजीबी डेटा को एक समय में एक से अधिक पिक्सेल डेटा (http://java.sun.com/javase/6/docs/api/java/awt/image/BufferedImage.html देखें), और आंतरिक लूप के प्रत्येक पुनरावृत्ति पर तीन रंग वस्तुओं को नहीं बनाकर आपके समाधान में सुधार किया जा सकता है।

final int width = image.getWidth(); 
int[] imgData = new int[width]; 
int[] maskData = new int[width]; 

for (int y = 0; y < image.getHeight(); y++) { 
    // fetch a line of data from each image 
    image.getRGB(0, y, width, 1, imgData, 0, 1); 
    mask.getRGB(0, y, width, 1, maskData, 0, 1); 
    // apply the mask 
    for (int x = 0; x < width; x++) { 
     int color = imgData[x] & 0x00FFFFFF; // mask away any alpha present 
     int maskColor = (maskData[x] & 0x00FF0000) << 8; // shift red into alpha bits 
     color |= maskColor; 
     imgData[x] = color; 
    } 
    // replace the data 
    image.setRGB(0, y, width, 1, imgData, 0, 1); 
} 
0

दरअसल, मैंने इसे समझ लिया है। यह संभवत: एक तेजी यह ऐसा करने का तरीका नहीं है, लेकिन यह काम करता है:

for (int y = 0; y < image.getHeight(); y++) { 
    for (int x = 0; x < image.getWidth(); x++) { 
     Color c = new Color(image.getRGB(x, y)); 
     Color maskC = new Color(mask.getRGB(x, y)); 
     Color maskedColor = new Color(c.getRed(), c.getGreen(), c.getBlue(), 
      maskC.getRed()); 
     resultImg.setRGB(x, y, maskedColor.getRGB()); 
    } 
} 
9

मैं हाल ही में इस सामान के साथ एक सा खेला जाता है, एक और एक के ऊपर एक छवि प्रदर्शित करने, और ग्रे के लिए एक छवि फीका करने के लिए।
पारदर्शिता के साथ एक मुखौटा के साथ एक छवि को मास्क करना (इस संदेश का मेरा पिछला संस्करण!)।

मैंने अपना छोटा परीक्षण कार्यक्रम लिया और वांछित परिणाम प्राप्त करने के लिए इसे थोड़ा सा tweaked।

यहाँ प्रासंगिक बिट कर रहे हैं:

TestMask() throws IOException 
{ 
    m_images = new BufferedImage[3]; 
    m_images[0] = ImageIO.read(new File("E:/Documents/images/map.png")); 
    m_images[1] = ImageIO.read(new File("E:/Documents/images/mapMask3.png")); 
    Image transpImg = TransformGrayToTransparency(m_images[1]); 
    m_images[2] = ApplyTransparency(m_images[0], transpImg); 
} 

private Image TransformGrayToTransparency(BufferedImage image) 
{ 
    ImageFilter filter = new RGBImageFilter() 
    { 
     public final int filterRGB(int x, int y, int rgb) 
     { 
      return (rgb << 8) & 0xFF000000; 
     } 
    }; 

    ImageProducer ip = new FilteredImageSource(image.getSource(), filter); 
    return Toolkit.getDefaultToolkit().createImage(ip); 
} 

private BufferedImage ApplyTransparency(BufferedImage image, Image mask) 
{ 
    BufferedImage dest = new BufferedImage(
      image.getWidth(), image.getHeight(), 
      BufferedImage.TYPE_INT_ARGB); 
    Graphics2D g2 = dest.createGraphics(); 
    g2.drawImage(image, 0, 0, null); 
    AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.DST_IN, 1.0F); 
    g2.setComposite(ac); 
    g2.drawImage(mask, 0, 0, null); 
    g2.dispose(); 
    return dest; 
} 

शेष बस थोड़ी स्विंग पैनल में छवियों को प्रदर्शित।
ध्यान दें कि मास्क छवि ग्रे स्तर है, काला पूर्ण पारदर्शिता बन रहा है, सफेद पूर्ण अपारदर्शी बन रहा है।

हालांकि आपने अपनी समस्या का समाधान किया है, हालांकि मैं इसे अपना लेना साझा कर सकता हूं। यह छवियों को संसाधित/फ़िल्टर करने के लिए मानक कक्षाओं का उपयोग करके थोड़ा और जावा-आश विधि का उपयोग करता है।
असल में, मेरी विधि थोड़ा और मेमोरी (अतिरिक्त छवि बनाने) का उपयोग करती है और मुझे यकीन नहीं है कि यह तेज़ है (संबंधित प्रदर्शन को मापना दिलचस्प हो सकता है), लेकिन यह थोड़ा और सार है।
कम से कम, आपके पास विकल्प है! :-)

21

मुझे इस उत्तर के साथ बहुत देर हो चुकी है, लेकिन शायद यह किसी के लिए भी उपयोग की जा सकती है। ,

public void applyGrayscaleMaskToAlpha(BufferedImage image, BufferedImage mask) 
{ 
    int width = image.getWidth(); 
    int height = image.getHeight(); 

    int[] imagePixels = image.getRGB(0, 0, width, height, null, 0, width); 
    int[] maskPixels = mask.getRGB(0, 0, width, height, null, 0, width); 

    for (int i = 0; i < imagePixels.length; i++) 
    { 
     int color = imagePixels[i] & 0x00ffffff; // Mask preexisting alpha 
     int alpha = maskPixels[i] << 24; // Shift blue to alpha 
     imagePixels[i] = color | alpha; 
    } 

    image.setRGB(0, 0, width, height, imagePixels, 0, width); 
} 

यह शुरुआत में एक सरणी में सभी पिक्सल पढ़ता इस प्रकार के लिए लूप केवल एक की आवश्यकता होती है: यह माइकल मायर्स 'विधि का एक सरल और अधिक कुशल संस्करण है। इसके अलावा, यह लाल बाइट को पहली बार मुखौटा करने और फिर इसे स्थानांतरित करने के बजाय नीले बाइट को अल्फा (मास्क रंग के) में सीधे बदल देता है।

अन्य तरीकों की तरह, यह मानता है कि दोनों छवियों में समान आयाम हैं।

0

उन लोगों के लिए जो मूल छवि में अल्फा का उपयोग कर रहे हैं।

मैंने इस कोड को कोल्तिन में लिखा था, यहां मुख्य बिंदु यह है कि यदि आपके पास अपनी मूल छवि पर अल्फा है तो आपको इन चैनलों को गुणा करने की आवश्यकता है।

Koltin संस्करण:

val width = this.width 
    val imgData = IntArray(width) 
    val maskData = IntArray(width) 

    for(y in 0..(this.height - 1)) { 

     this.getRGB(0, y, width, 1, imgData, 0, 1) 
     mask.getRGB(0, y, width, 1, maskData, 0, 1) 

     for (x in 0..(this.width - 1)) { 

     val maskAlpha = (maskData[x] and 0x000000FF)/ 255f 
     val imageAlpha = ((imgData[x] shr 24) and 0x000000FF)/255f 
     val rgb = imgData[x] and 0x00FFFFFF 
     val alpha = ((maskAlpha * imageAlpha) * 255).toInt() shl 24 
     imgData[x] = rgb or alpha 
     } 
     this.setRGB(0, y, width, 1, imgData, 0, 1) 
    } 

जावा एक वैकल्पिक तरीका में संस्करण (केवल Kotlin से अनुवाद)

int width = image.getWidth(); 
    int[] imgData = new int[width]; 
    int[] maskData = new int[width]; 

    for (int y = 0; y < image.getHeight(); y ++) { 

     image.getRGB(0, y, width, 1, imgData, 0, 1); 
     mask.getRGB(0, y, width, 1, maskData, 0, 1); 

     for (int x = 0; x < image.getWidth(); x ++) { 

      //Normalize (0 - 1) 
      float maskAlpha = (maskData[x] & 0x000000FF)/ 255f; 
      float imageAlpha = ((imgData[x] >> 24) & 0x000000FF)/255f; 

      //Image without alpha channel 
      int rgb = imgData[x] & 0x00FFFFFF; 

      //Multiplied alpha 
      int alpha = ((int) ((maskAlpha * imageAlpha) * 255)) << 24; 

      //Add alpha to image 
      imgData[x] = rgb | alpha; 
     } 
     image.setRGB(0, y, width, 1, imgData, 0, 1); 
    } 
संबंधित मुद्दे