2011-10-17 16 views
10

मैं एक पृष्ठ लोड करने और प्रतिपादन को एक छवि के रूप में सहेजने का तरीका ढूंढ रहा हूं जैसे कि आप क्यूटी कैप्टन (QT + webkit EXE के साथ ऐसा करेंगे))।जावाएफएक्स 2.0+ वेबव्यू/वेबइंजिन एक छवि को वेब पेज प्रस्तुत करें

फिलहाल और JavaFX के बिना, मैं यह जावा से एक बाहरी प्रक्रिया बुला और एक ImageBuffer में है कि फ़ाइल लोड करने से दाखिल करने के लिए प्रतिपादन से कर ... न तो बहुत अनुकूलित है और न ही व्यावहारिक और भी कम क्रॉस प्लेटफॉर्म ...

JavaFX2 का उपयोग + मैं WebView के साथ खेल की कोशिश की & WebEngine:

public class WebComponentTrial extends Application { 
    private Scene scene; 

    @Override 
    public void start(final Stage primaryStage) throws Exception { 
     primaryStage.setTitle("Web View"); 
     final Browser browser = new Browser(); 
     scene = new Scene(browser, 1180, 800, Color.web("#666970")); 
     primaryStage.setScene(scene); 
     scene.getStylesheets().add("webviewsample/BrowserToolbar.css"); 
     primaryStage.show(); 
    } 

    public static void main(final String[] args) { 
     launch(args); 
    } 
} 
class Browser extends Region { 
    static { // use system proxy settings when standalone application 
    // System.setProperty("java.net.useSystemProxies", "true"); 
    } 

    final WebView browser = new WebView(); 
    final WebEngine webEngine = browser.getEngine(); 

    public Browser() { 
     getStyleClass().add("browser"); 
     webEngine.load("http://www.google.com/"); 
     getChildren().add(browser); 
    } 

    @Override 
    protected void layoutChildren() { 
     final double w = getWidth(); 
     final double h = getHeight(); 
     layoutInArea(browser, 0, 0, w, h, 0, HPos.CENTER, VPos.CENTER); 
    } 

    @Override 
    protected double computePrefWidth(final double height) { 
     return 800; 
    } 

    @Override 
    protected double computePrefHeight(final double width) { 
     return 600; 
    } 
} 

एक पदावनत विधि है: Scene में renderToImage (नीचे लिंक देखें) है कि कुछ आता है कि क्या करना होगा करीब है और जिसके साथ मैं सक्षम हो सकता है चाहता हूँ काम करने के लिए लेकिन इसे बहिष्कृत किया गया है ... जावाएफएक्स में इसे बहिष्कृत किया जा रहा है, इसका मतलब यह है कि प्रतिस्थापन विधि का कोई जवाडोक विज्ञापन नहीं है और क्योंकि मेरे पास कोड तक पहुंच नहीं है, मैं नहीं देख सकता कि यह कैसे किया गया था ...

यहां कुछ साइटें हैं जहाँ मैं कुछ जानकारी है, लेकिन कुछ भी नहीं मिला एक छवि के लिए एक वेबपेज प्रस्तुत करना: यह एक से

http://tornorbye.blogspot.com/2010/02/how-to-render-javafx-node-into-image.html 

canvasImage और saveImage(canvasImage, fc.getSelectedFile()):

http://javafx.com/samples/EffectsPlayground/src/Main.fx.html 

अन्य:

http://download.oracle.com/javafx/2.0/webview/jfxpub-webview.htm 
http://download.oracle.com/javafx/2.0/get_started/jfxpub-get_started.htm 
http://fxexperience.com/2011/05/maps-in-javafx-2-0/ 

उत्तर

8

मैंने एक स्विंग जेएफआरएएम और जेएफएक्सपैनल पर जावाएफएक्स वेबव्यू लॉन्च करके ऐसा किया है। और फिर WebEngine स्थिति सफल होने के बाद मैं जेएफएक्स पैनेल पर पेंट() विधि का उपयोग करता हूं।

नीचे कोड का प्रदर्शन कैसे मैं JFXPanel से प्रदान की गई स्क्रीन पर कब्जा:

आप एक WebView बनाने के लिए इस ट्यूटोरियल का पालन कर सकते हैं।

public static void main(String args[]) { 
    jFrame = new JFrame("Demo Browser"); 
    jfxPanel = new JFXPanel(); 
    jFrame.add(jfxPanel); 
    jFrame.setVisible(true); 
    jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    SwingUtilities.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
      Platform.runLater(new Runnable() { 
       @Override 
       public void run() { 
        browser = new FXBrowser(); 
        jfxPanel.setScene(browser.getScene()); 
        jFrame.setSize((int) browser.getWebView().getWidth(), (int) browser.getWebView().getHeight()); 

        browser.getWebEngine().getLoadWorker().stateProperty().addListener(
          new ChangeListener() { 
           @Override 
           public void changed(ObservableValue observable, 
                Object oldValue, Object newValue) { 
            State oldState = (State) oldValue; 
            State newState = (State) newValue; 
            if (State.SUCCEEDED == newValue) { 
             captureView(); 
            } 
           } 
          }); 
       } 
      }); 
     } 
    }); 
} 

private static void captureView() { 
    BufferedImage bi = new BufferedImage(jfxPanel.getWidth(), jfxPanel.getHeight(), BufferedImage.TYPE_INT_ARGB); 
    Graphics graphics = bi.createGraphics(); 
    jfxPanel.paint(graphics); 
    try { 
     ImageIO.write(bi, "PNG", new File("demo.png")); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    graphics.dispose(); 
    bi.flush(); 
} 
+0

मैं 'पेंट' पर 'प्रिंट' या 'प्रिंटअल' का उपयोग करता हूं, लेकिन बुनियादी विचार तरीका शांत है! – MadProgrammer

+0

FXBrowser क्या है? – Pablo

2

वर्कअराउंड जावाएफएक्स इंजीनियरों द्वारा पोस्ट किया गया: Snapshot does not work with (invisible) WebView nodes

जब एक दृश्य है कि एक WebView नोड शामिल का एक स्नैपशॉट ले, snapshot आदेश जारी करने से पहले कम से कम 2 फ्रेम के लिए प्रतीक्षा करें। यह 2 दालों को छोड़ने और तीसरी पल्स पर स्नैपशॉट लेने के लिए AnimationTimer में एक काउंटर का उपयोग करके किया जा सकता है।

बार जब आप अपने स्नैपशॉट मिल गया है, तो आप एक AWT BufferedImage करने के लिए छवि बदलने और छवि सांकेतिक शब्दों में बदलना PNG या JPG तरह स्वरूपित करने के लिए, ImageIO का उपयोग कर सकते हैं।

+2

इस मुद्दे का नया लिंक: https://bugs.openjdk.java.net/browse/JDK-8087569 –

7

जावाएफएक्स 2.2 उपयोगकर्ताओं के लिए जावाएफएक्स नोड स्नैपशॉट के आधार पर एक और अधिक स्वच्छ और सुरुचिपूर्ण समाधान है।

http://docs.oracle.com/javafx/2/api/javafx/scene/Node.html

यहाँ एक पर कब्जा (WebView के रूप में) एक WebView नोड से ले रही है

File destFile = new File("test.png"); 
    WritableImage snapshot = webView.snapshot(new SnapshotParameters(), null); 
    RenderedImage renderedImage = SwingFXUtils.fromFXImage(snapshot, null); 
    try { 
     ImageIO.write(renderedImage, "png", destFile); 
    } catch (IOException ex) { 
     Logger.getLogger(GoogleMap.class.getName()).log(Level.SEVERE, null, ex); 
    } 

मैं इस समाधान के साथ कोई समस्या नहीं थी का एक उदाहरण है: आप पर JavaFX नोड प्रलेखन के लिए एक बार देख ले सकते हैं , और वेबव्यू नोड आकार के अनुसार पीएनजी में पूरी तरह से प्रस्तुत किया जाता है। किसी भी जावाएफएक्स नोड को इस विधि के साथ फाइल में प्रस्तुत किया जा सकता है और सहेजा जा सकता है।

इस सहायता की आशा करें!

+0

लेकिन हेडलेस स्क्रीनशॉटिंग के बारे में क्या? तो टोपी मैं इसे सर्वर पक्ष पर लॉन्च कर सकता हूं ताकि फ़ैंटॉमजेएस – ses

+0

के साथ स्क्रीनशॉट ले सकें क्षमा करें, लेकिन मुझे आपको –

+1

समझ में नहीं आता है, मैं सिर्फ काम करने वाले उदाहरण की तलाश कर रहा हूं जो किसी भी फॉर्म/फ्रेम - "हेडलेस" को दिखाए बिना स्नैपशॉट ले सकता है। ऐप लॉन्च करने की तरह, यह स्क्रीन पर किसी भी विंडो को दिखाए बिना जो भी एचटीएमएल पास करता है, उसका स्नैपशॉट लेता है। PhantomJS की तरह करता है। – ses