पृष्ठभूमि: मुझे "अक्षम" रूप में इमेजरी बनाने में सक्षम होना चाहिए। आमतौर पर सुझाए गए दृष्टिकोण छवियों को ग्रेस्केल में कनवर्ट करना और ग्रेस्केल छवि दिखाएं। दोष यह है कि यह केवल छवियों के साथ काम करता है, जिससे ग्राफिक्स दिखाने के लिए यह बोझिल हो जाता है जहां आपके पास अक्षम स्थिति में किसी छवि की तत्काल पहुंच नहीं है। अब मैंने सोचा था कि यह java.awt.Composite के साथ फ्लाई पर किया जा सकता है (और फिर मुझे यह जानने की आवश्यकता नहीं होगी कि उदाहरण के लिए कैसे एक आइकन इसे अक्षम करने के लिए लागू किया गया है)। केवल ग्रेस्केल में कनवर्ट करने के लिए कोई कार्यान्वयन नहीं होता है, इसलिए मुझे अपना खुद का निर्माण करना पड़ा ...मैं java.awt.Composite को कुशलतापूर्वक कैसे कार्यान्वित कर सकता हूं?
उस ने कहा, मैंने एक कार्यान्वयन को एक साथ जोड़ दिया है (और यह मुझे इसकी अपेक्षा करता है)। लेकिन मुझे यकीन नहीं है कि यह वास्तव में सभी मामलों के लिए सही ढंग से काम करेगा (समग्र/कंपोजिट कॉन्टेक्स्ट के जावाडॉक्स इस तरह के जटिल ऑपरेशन के लिए बेहद पतले लगते हैं)। और जैसा कि आप मेरे कार्यान्वयन से देख सकते हैं, मैं पिक्सेल द्वारा पिक्सेल को संसाधित करने के लिए एक चौराहे के रास्ते पर जाता हूं, क्योंकि इसमें शामिल रास्टर्स द्वारा निर्धारित प्रारूप में थोक में पिक्सल पढ़ने/लिखने का कोई आसान तरीका नहीं लगता है।
अधिक व्यापक दस्तावेज़ीकरण/उदाहरण/संकेतों के लिए कोई भी संकेतक स्वागत है।
यहां एसएससीसीई है - यह ग्रेडियेंट को ग्रेस्केल में परिवर्तित करने के लिए अक्षम कॉम्पोजिट के माध्यम से एक (रंगीन) ग्रेडियेंटेंट प्रस्तुत करता है। ध्यान दें कि वास्तविक दुनिया में आप नहीं जानते क्या कॉल के साथ प्रस्तुत किया जाता है। ग्रेडियंट वास्तव में केवल एक उदाहरण है (क्षमा करें, लेकिन अक्सर लोग इसे प्राप्त नहीं करते हैं, इसलिए मैं इसे इस बार स्पष्ट कर दूंगा)।
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Composite;
import java.awt.CompositeContext;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class CompositeSSCE implements Runnable {
static class DisabledComposite implements Composite {
@Override
public CompositeContext createContext(
final ColorModel srcColorModel,
final ColorModel dstColorModel,
final RenderingHints hints) {
return new DisabledCompositeContext(srcColorModel, dstColorModel);
}
}
static class DisabledCompositeContext implements CompositeContext {
private final ColorModel srcCM;
private final ColorModel dstCM;
final static int PRECBITS = 22;
final static int WEIGHT_R = (int) ((1 << PRECBITS) * 0.299);
final static int WEIGHT_G = (int) ((1 << PRECBITS) * 0.578);
final static int WEIGHT_B = (int) ((1 << PRECBITS) * 0.114);
final static int SRCALPHA = (int) ((1 << PRECBITS) * 0.667);
DisabledCompositeContext(final ColorModel srcCM, final ColorModel dstCM) {
this.srcCM = srcCM;
this.dstCM = dstCM;
}
public void compose(final Raster src, final Raster dstIn, final WritableRaster dstOut) {
final int w = Math.min(src.getWidth(), dstIn.getWidth());
final int h = Math.min(src.getHeight(), dstIn.getHeight());
for (int y = 0; y < h; ++y) {
for (int x = 0; x < w; ++x) {
int rgb1 = srcCM.getRGB(src.getDataElements(x, y, null));
int a1 = ((rgb1 >>> 24) * SRCALPHA) >> PRECBITS;
int gray = (
((rgb1 >> 16) & 0xFF) * WEIGHT_R +
((rgb1 >> 8) & 0xFF) * WEIGHT_G +
((rgb1 ) & 0xFF) * WEIGHT_B
) >> PRECBITS;
int rgb2 = dstCM.getRGB(dstIn.getDataElements(x, y, null));
int a2 = rgb2 >>> 24;
int r2 = (rgb2 >> 16) & 0xFF;
int g2 = (rgb2 >> 8) & 0xFF;
int b2 = (rgb2 ) & 0xFF;
// mix the two pixels
gray = gray * a1/255;
final int ta = a2 * (255 - a1);
r2 = gray + (r2 * ta/(255*255));
g2 = gray + (g2 * ta/(255*255));
b2 = gray + (b2 * ta/(255*255));
a2 = a1 + (ta/255);
rgb2 = (a2 << 24) | (r2 << 16) | (g2 << 8) | b2;
Object data = dstCM.getDataElements(rgb2, null);
dstOut.setDataElements(x, y, data);
}
}
}
@Override
public void dispose() {
// nothing for this implementation
}
}
// from here on out its only the fluff to make this a runnable example
public static void main(String[] argv) {
Runnable r = new CompositeSSCE();
SwingUtilities.invokeLater(r);
}
// simple component to use composite to render
static class DemoComponent extends JComponent {
// demonstrate rendering an icon in grayscale with the composite
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
GradientPaint p = new GradientPaint(0, 0, Color.GREEN, 127, 127, Color.BLUE, true);
g2d.setComposite(new DisabledComposite());
g2d.setPaint(p);
g2d.fillRect(0, 0, getWidth(), getHeight());
}
}
// Fluff to use the Composite in Swing
public void run() {
try {
JFrame f = new JFrame("Test grayscale composite");
DemoComponent c = new DemoComponent();
c.setPreferredSize(new Dimension(500, 300));
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new BorderLayout());
f.add(c, BorderLayout.CENTER);
f.pack();
f.setVisible(true);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
ब्लेंडकंपोसाइट एक उपयोगी टूल की तरह दिखता है, संकेत के लिए धन्यवाद। हालांकि एक त्वरित नज़र से ऐसा लगता है कि हर संभव रंगमोडल के साथ इसकी रचना() - विधि में काम नहीं करता है, शायद अन्य रंग मॉडल अभ्यास में प्रासंगिक नहीं हैं? "आप हमेशा एक बुफर्ड इमेज बना सकते हैं" के रूप में, मैं नहीं देखता कि मैं इसे कैसे बना सकता हूं() - विधि कार्यान्वयन। इसे पेंट कॉम्पोनेंट() में कहीं भी करना संभव होगा, लेकिन यह समग्र सेट करने की तुलना में बहुत कम लचीला है और फिर सामान्य प्रतिपादन श्रृंखला के साथ आगे बढ़ें। – Durandal
@ डुरंडल मुझे नहीं पता कि यह सभी रंग मॉडल के लिए उपयुक्त है (और मुझे नहीं पता कि इस संदर्भ में रंगमोडेल का क्या उपयोग किया जाता है, हालांकि मैं अनुमान लगा सकता हूं), जो मुझे पता है, और जिस कारण से मैंने सुझाव दिया है, स्विंगएक्स ने आधिकारिक स्विंग टीम से इनपुट किया है, इसलिए इसे सामान्य उपयोगों के लिए लचीला होना चाहिए। मेरे पहले सुझाव के साथ, आप कंपोजिट का उपयोग नहीं करेंगे, और मैं इसे पेंट कॉम्पोनेंट में करूँगा - यह उतना ही लचीला है, बस अधिक काम (ड्राइंग आकार में छवि बनाएं, इसे खींचें, इसे फ़िल्टर करें, इसे पेंट करें; और कैश आकार का उपयोग करने के लिए आखिरी वाला उपयोग करें) .... – Tom
@ डुरंडल आप BufferedImage के लिए 'ग्राफिक्स' बना सकते हैं और उसके बाद उस ग्राफिक्स उदाहरण के साथ 'paintComponent' को कॉल कर सकते हैं। – Tom