[Java] यह लाइन उचित एंटीअलाइजिंग के बिना क्यों प्रस्तुत की जाती है?



Answers

आपके द्वारा देखे जाने वाले व्यवहार इस तथ्य से संबंधित नहीं हैं कि रेखा कैनवास के बाहर शुरू होती है। यदि आप कैनवास के अंदर पूरी तरह से एक लाइन का उपयोग करते हैं तो आप वही व्यवहार देखेंगे।

समस्या एक छोटी ढलान dy/dx=1/90 , एक छोटी चौड़ाई ( 2 ) और एंटीअलाइजिंग एल्गोरिदम के संयोजन से आ रही है।

एंटीअलाइजिंग के बिना

    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                       RenderingHints.VALUE_ANTIALIAS_OFF);

एंटीअलाइजिंग के साथ

    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                       RenderingHints.VALUE_ANTIALIAS_ON);

आपके द्वारा देखे जाने वाले व्यवहार पूरी तरह से सामान्य हैं और एंटीअलाइजिंग एल्गोरिदम के कारण हैं।

Question

मैं एक लाइन प्रस्तुत करने की कोशिश कर रहा हूं, लेकिन यदि वास्तविक कैनवास सीमाओं के बाहर लाइन शुरू होती है, तो मुझे अजीब व्यवहार मिलता है।

उदाहरण के लिए, मुझे कभी-कभी उचित छवि के बजाय यह छवि मिलती है:

उचित रेखा इस तरह दिखाई देगी:

इस नमूने को उत्पन्न करने के लिए रननेबल कोड यहां दिया गया है:

import java.awt.image.*;
import javax.imageio.ImageIO;
import java.io.File;
import java.awt.*;
import java.awt.geom.*;

public class Render {
    public static void main(String[] args) throws Exception {
        BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = (Graphics2D) image.getGraphics();

        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
        g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);

        g.setColor(Color.WHITE);
        g.fillRect(0, 0, 100, 100);

        g.setColor(Color.BLACK);
        g.setStroke(new BasicStroke(2));
        g.draw(new Line2D.Double(-92, 37, 88, 39));

        g.dispose();
        ImageIO.write(image, "png", new File("output.png"));
    }
}

मैंने कई अलग-अलग प्रतिपादन संकेतों का उपयोग करने की कोशिश की, लेकिन इस समस्या से कोई संयोजन छुटकारा नहीं मिलता है। अपराधी क्या हो सकता है?

संपादित करें :

RenderingHints.VALUE_STROKE_NORMALIZE के साथ छवि यहां दी गई है:

छवि का स्केल संस्करण ( g.scale(10,10) ):




मेरी राय में, कैनवास के बाहर अपनी लाइन शुरू करते समय यह एंटीअलाइजिंग एल्गोरिदम में एक बग है।

रेंडरिंगहिंट्स के साथ बहुत कुछ खेलने के बाद, लाइन पिक्सेल को पिक्सेल द्वारा ले जाना और ढलान, लंबाई, भाग में और कैनवास के बाहर कुछ मूल्यों का विश्लेषण करना, मैं निष्कर्ष पर आया, कि यदि आप वास्तव में गहरी नहीं बनना चाहते हैं हाथ में एंटीअलाइजिंग एल्गोरिदम जिस तरह से काम करता है, आप शायद उचित कार्यवाही से संतुष्ट होंगे:

  1. अंतिम कैनवास के चारों ओर एक विशाल सुरक्षा के साथ शुरू करें।
  2. सामान्य रूप से छवि को खींचे, बस सुरक्षित स्थान की सीमा से स्थानांतरित हो जाएं।
  3. सुरक्षा को दूर करो।

उदाहरण के लिए:

import java.awt.image.*;
import javax.imageio.ImageIO;
import java.io.File;
import java.awt.*;
import java.awt.geom.*;

public class Render {
    public static void main(String[] args) throws Exception {

        // YOUR DESIRED SIZE OF CANVAS
        int size = 100;
        // THE SAFEZONE AROUND THE CANVAS
        int safezone = 1000;

        // THE IMAGE GETS INITIALIZED WITH SAFEZONE APPLIED
        BufferedImage image = new BufferedImage(size+safezone, size+safezone, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = (Graphics2D) image.getGraphics();

        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
        g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);

        g.setColor(Color.WHITE);

        // THE IMAGE GETS FILLED, DON'T FORGET THE SAFEZONE
        g.fillRect(0, 0, size+safezone, size+safezone);

        // THE ORIGINAL VALUES WITH THE SAFEZONE APPLIED
        int x1 = -92 + safezone/2;
        int x2 = 88 + safezone/2;
        int y1 = 37 + safezone/2;
        int y2 = 39 + safezone/2;

        g.setColor(Color.BLACK);
        g.setStroke(new BasicStroke(2));
        g.draw(new Line2D.Double(x1, y1, x2, y2));

        g.dispose();

        // CROP THE IMAGE
        image = image.getSubimage(safezone/2, safezone/2, size, size);
        ImageIO.write(image, "png", new File("output.png"));
    }
}

यह आपको देगा:

अपने सटीक मूल्यों का उपयोग करते समय। कोड निश्चित रूप से आपकी जरूरतों के अनुरूप होना चाहिए, लेकिन उदाहरण के लिए, यह काम करता है।

हालांकि यह एक सुंदर समाधान नहीं है, परिणाम हैं और मुझे उम्मीद है कि यह मदद करता है! :)




Links