2012-05-01 187 views
10

對於我的應用程序,我需要動態創建網站縮略圖。到目前爲止,我有這個代碼從SO:生成網站縮略圖?

public class CreateWebsiteThumbnail { 

    private static final int WIDTH = 128; 
    private static final int HEIGHT = 128; 

    private BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); 

    public void capture(Component component) { 
     component.setSize(image.getWidth(), image.getHeight()); 

     Graphics2D g = image.createGraphics(); 
     try { 
       component.paint(g); 
     } finally { 
       g.dispose(); 
     } 
    } 

    private BufferedImage getScaledImage(int width, int height) { 
     BufferedImage buffer = new BufferedImage(width, height, 
         BufferedImage.TYPE_INT_RGB); 
     Graphics2D g = buffer.createGraphics(); 
     try { 
       g.drawImage(image, 0, 0, width, height, null); 
     } finally { 
       g.dispose(); 
     } 
     return buffer; 
    } 

    public void save(File png, int width, int height) throws IOException { 
     ImageIO.write(getScaledImage(width, height), "png", png); 
    } 

    public static void main(String[] args) throws IOException { 

     Shell shell = new Shell(); 
     Browser browser = new Browser(shell, SWT.EMBEDDED); 
     browser.setUrl("http://www.google.com"); 


     CreateWebsiteThumbnail cap = new CreateWebsiteThumbnail(); 
     cap.capture(What her?); 
     cap.save(new File("foo.png"), 64, 64); 
    } 


} 

但正如你所看到的,我不知道我應該傳遞給我的捕捉方法使瀏覽器的一部分。任何提示?

+0

除非您計算您的縮略圖寬度和高度與網站圖片的寬度和高度成正比,否則您將得到一個扭曲的縮略圖。 –

+0

@GilbertLeBlanc現在我會很高興,如果我能得到任何縮略圖 – RoflcoptrException

+0

我要等着看,如果有人有答案,但據我所知,瀏覽器類沒有辦法獲得網絡圖像頁。如果您使用的是Swing,我會建議使用Robot類來獲取圖像。 –

回答

10

我沒有看到,您提供的代碼如何工作。 Shell沒有打開,它沒有大小,Browser沒有得到實際加載任何東西的時間,沒有任何事件循環似乎在運行以啓用任何繪圖,...

以下代碼不會執行屏幕截圖網頁使用SWT瀏覽器:

import java.io.IOException; 

import org.eclipse.swt.SWT; 
import org.eclipse.swt.browser.Browser; 
import org.eclipse.swt.browser.ProgressEvent; 
import org.eclipse.swt.browser.ProgressListener; 
import org.eclipse.swt.graphics.GC; 
import org.eclipse.swt.graphics.Image; 
import org.eclipse.swt.graphics.ImageData; 
import org.eclipse.swt.graphics.ImageLoader; 
import org.eclipse.swt.layout.FillLayout; 
import org.eclipse.swt.widgets.Display; 
import org.eclipse.swt.widgets.Shell; 


public class CreateWebsiteThumbnail { 

    private static final int WIDTH = 800; 
    private static final int HEIGHT = 600; 


    public static void main(String[] args) throws IOException { 
     final Display display = new Display(); 
     final Shell shell = new Shell(); 
     shell.setLayout(new FillLayout()); 
     final Browser browser = new Browser(shell, SWT.EMBEDDED); 
     browser.addProgressListener(new ProgressListener() { 

     @Override 
     public void changed(ProgressEvent event) {} 

     @Override 
     public void completed(ProgressEvent event) { 
      shell.forceActive(); 
      display.asyncExec(new Runnable() { 

       @Override 
       public void run() { 
        grab(display, shell, browser); 
       } 
      }); 

     } 
     }); 
     browser.setUrl("http://www.google.com"); 

     shell.setSize(WIDTH, HEIGHT); 
     shell.open(); 

     while (!shell.isDisposed()) { 
     if (!display.readAndDispatch()) display.sleep(); 
     } 
     display.dispose(); 
    } 

    private static void grab(final Display display, final Shell shell, final Browser browser) { 
     final Image image = new Image(display, browser.getBounds()); 
     GC gc = new GC(browser); 
     gc.copyArea(image, 0, 0); 
     gc.dispose(); 

     ImageLoader loader = new ImageLoader(); 
     loader.data = new ImageData[] { image.getImageData() }; 
     loader.save("foo.png", SWT.IMAGE_PNG); 
     image.dispose(); 

     shell.dispose(); 
    } 

} 

但也有一些嚴重的警告:

  • 你不能做到這一點關閉屏幕。SWT截圖只是當前顯示的副本。
  • 截圖時,包含瀏覽器的窗口必須位於最前面。
  • onLoad之後頁面應該是可見的(實際上google.com並不是這樣,但因爲asyncExec調用,我的作品無論如何 - 如果您獲得白色圖像,請嘗試另一個URL)
  • 結果是取決於你的操作系統和它安裝的瀏覽器

我會去與非Java的解決方案,爲了脫離屏幕繪圖。我相信這個相關問題可能會幫助你進一步得到。

+0

夥計們不會向'Shall'對象添加一個'PaintListener',在那裏你可以爲圖像做繪畫,在這種情況下工作?就像在這個「SWT」的繪畫教程中,http://zetcode.com/tutorials/javaswttutorial/painting/ – Boro

+0

謝謝,這看起來正是我正在尋找的東西。但是,我總是會得到一個空的圖像(只是默認背景)。即使我不渲染離屏,也會發生這種情況。即瀏覽器始終可見。 – RoflcoptrException

+0

@ the.duckmann通知您有關以前的評論;) – RoflcoptrException

4

據我所知,當您使用瀏覽器對象時,您加載的網頁直接呈現在您通過構造函數傳遞給它的Composite對象上。在你的情況下,它會呈現在你的Shell項目上,這是一個窗口樣式的對象。沒有辦法直接在網頁上渲染網頁,比如Image對象。

雖然您可以嘗試在Canvas對象上實例化您的瀏覽器,並直接從那裏保存圖像。

不幸的是,我無法測試這是否有效,因爲我既沒有安裝Eclipse也沒有安裝SWT,我很確定,如果你想做的事情是可行的,這是唯一的方法。

3

我做了一些實驗。我的直覺就像上面提到的in the answer your code is based on.一樣嘗試JEditorPane我不知道它會有多大的幫助,但它可能會有所幫助。我給出了一些結果,但從明顯的原因,運氣的css支持等在JEditorPane它看起來都很醜陋。

這是我的代碼:

import java.awt.BorderLayout; 
import java.awt.Component; 
import java.awt.Graphics2D; 
import java.awt.event.ActionEvent; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import java.net.URL; 
import javax.imageio.ImageIO; 
import javax.swing.*; 
import javax.swing.text.html.HTMLEditorKit; 

public class WebPageToImageThumbnail { 

    public static void main(String[] a) throws Exception { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       JFrame frame = new JFrame(); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       final JEditorPane editorPane = new JEditorPane(); 
       editorPane.setEditorKit(new HTMLEditorKit()); 
       try { 
        editorPane.setPage(new URL("http://weblogs.java.net/blog/alex2d/archive/2008/12/jwebpane_projec.html")); 
       } catch (IOException ex) { 
       } 
       final JPanel panel = new JPanel(new BorderLayout()); 
       panel.add(new JScrollPane(editorPane), BorderLayout.CENTER); 
       panel.add(new JButton(new AbstractAction("SAVE") { 
        @Override 
        public void actionPerformed(ActionEvent e) { 
         BufferedImage image = capture(editorPane); 
         try { 
          save(image, new File("foo.png"), 64, 64); 
         } catch (IOException ex) { 
         } 
        } 
       }), BorderLayout.SOUTH); 
       frame.setContentPane(panel); 
       frame.setSize(600, 400); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public static BufferedImage capture(Component component) { 
     BufferedImage image = new BufferedImage(component.getWidth(), component.getHeight(), BufferedImage.TYPE_INT_RGB);//component.setSize(image.getWidth(), image.getHeight()); 
     Graphics2D g = image.createGraphics(); 
     try { 
      component.paint(g); 
     } finally { 
      g.dispose(); 
     } 
     return image; 
    } 

    private static BufferedImage getScaledImage(BufferedImage image, int width, int height) { 
     BufferedImage buffer = new BufferedImage(width, height, 
       BufferedImage.TYPE_INT_RGB); 
     Graphics2D g = buffer.createGraphics(); 
     try { 
      g.drawImage(image, 0, 0, width, height, null); 
     } finally { 
      g.dispose(); 
     } 
     return buffer; 
    } 

    public static void save(BufferedImage image, File png, int width, int height) throws IOException { 
     ImageIO.write(getScaledImage(image, width, height), "png", png); 
    } 
} 

我也做了一些挖關於SWT我發現了一些認爲可能是有用的,但因爲我目前的運氣的時候,我無法測試。從我閱讀的內容來看,我必須同意@Emanuele Bezzi(+1),我們將不得不使用殼牌來獲取該網站的內容,而在這個網站中,我們實際上只對其感興趣。

我發現Shell具有print方法,這需要GC對象,它可以畫包括圖片和其他有趣的給我們的東西,該文件說:「GC類是所有的繪圖功能由SWT支持是實例用於繪製圖像,控件或直接在顯示器上繪製。「

然而,在這個特殊的時刻,我不清楚如何正確地把它做到我想做的。無論如何,我提出這一點只是爲了讓你知道。我仍然需要進一步研究。

2

也許你最好從一開始就讓頁面脫離屏幕。對於這樣的任務,您可以使用「飛碟」(僅限於xhtml,因此您需要整理)。似乎也有一些工具可以直接從Java接口Webkit。