Capture d'écran d'une WebView

Bonjour,



Je cherche à  créer une capture d'écran d'une webview d'une manière propre.

J'ai essayé d'utilisé le code suivant:
<br />
NSBitmapImageRep *bitmapRepRight = [[webView mainFrame].frameView bitmapImageRepForCachingDisplayInRect:cacheRect];<br />
[[[webView mainFrame].frameView  documentView] layout];<br />
[[webView mainFrame].frameView cacheDisplayInRect:cacheRect toBitmapImageRep:bitmapRepRight];<br />
return   [bitmapRepRight CGImage];<br />




dans la fonction:
<br />
- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame<br />




Je n'obtiens malheureusement que le fond de la page et jamais le reste (texte, images, ...)



Si je déporte le code de capture dans une fonction et qu'à  partir du didFinishLoadForFrame je l'appelle de la façon suivante:
<br />
[self performSelector:@selector(addPagesToCache) withObject:nil afterDelay:0.01];<br />




Cela fonctionne parfaitement.



Seulement voilà , cette manière de faire ne me satisfait pas du tout.

Avez-vous une idée d'où peut venir le problème et ce que l'on pourrait faire pour le résoudre?



Merci pour votre aide image/smile.png' class='bbc_emoticon' alt=':)' />

Réponses

  • 'AP' a écrit:


    Bonjour,



    Je cherche à  créer une capture d'écran d'une webview d'une manière propre.

    J'ai essayé d'utilisé le code suivant:
    <br />
    NSBitmapImageRep *bitmapRepRight = [[webView mainFrame].frameView bitmapImageRepForCachingDisplayInRect:cacheRect];<br />
    [[[webView mainFrame].frameView  documentView] layout];<br />
    [[webView mainFrame].frameView cacheDisplayInRect:cacheRect toBitmapImageRep:bitmapRepRight];<br />
    return   [bitmapRepRight CGImage];<br />
    




    dans la fonction:
    <br />
    - (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame<br />
    




    Je n'obtiens malheureusement que le fond de la page et jamais le reste (texte, images, ...)



    Si je déporte le code de capture dans une fonction et qu'à  partir du didFinishLoadForFrame je l'appelle de la façon suivante:
    <br />
    [self performSelector:@selector(addPagesToCache) withObject:nil afterDelay:0.01];<br />
    




    Cela fonctionne parfaitement.



    Seulement voilà , cette manière de faire ne me satisfait pas du tout.

    Avez-vous une idée d'où peut venir le problème et ce que l'on pourrait faire pour le résoudre?



    Merci pour votre aide image/smile.png' class='bbc_emoticon' alt=':)' />




    Trouvé sur le net:


    <br />
        Capturing webpage with frames using WebKit<br />
        NSView *docView = [[[webView mainFrame] frameView] documentView];<br />
        NSBitmapImageRep *imageRep = [docView  bitmapImageRepForCachingDisplayInRect: [docView frame]];<br />
        [docView cacheDisplayInRect: [docView frame] toBitmapImageRep:imageRep];<br />
        CIImage *webPageImage = [[CIImage alloc] initWithBitmapImageRep: imageRep];<br />
    




    A voir image/smile.png' class='bbc_emoticon' alt=':)' />
  • Merci pour ta réponse. J'ai testé cette solution mais même problème. Le problème ne semble pas venir de la capture mais du moment où je la fait. didFinishLoadForFrame semble être lancé trop tôt.
  • Peut-être ca ?


    <br />
    //  MWWebSnapshot<br />
    //<br />
    //  Created by Jim McGowan on 08/09/2010.<br />
    //  Copyright 2010 Jim McGowan. All rights reserved.<br />
    //<br />
    //  This code is made available under the BSD license.<br />
    //  Please see the accompanying license.txt file<br />
    //  or view the license online at http://www.malkinware.com/developer/License.txt<br />
    //<br />
    <br />
    #import &lt;Cocoa/Cocoa.h&gt;<br />
    #import &lt;WebKit/WebKit.h&gt;<br />
    <br />
    <br />
    @interface MWWebSnapshot : NSObject<br />
    {<br />
        void (^completionBlock)(NSImage *image);<br />
        WebView *webView;<br />
    }<br />
    <br />
    + (void)takeSnapshotOfWebPageAtURL:(NSURL *)url completionBlock:(void (^)(NSImage *))block;<br />
    <br />
    @end<br />
    <br />
    <br />
    <br />
    @interface MWWebSnapshot()<br />
    - (id)_initWithCompletionBlock:(void (^)(NSImage *))block;<br />
    - (void)_beginDownloadFromURL:(NSURL *)url;<br />
    @end<br />
    <br />
    <br />
    <br />
    @implementation MWWebSnapshot<br />
    <br />
    <br />
    + (void)takeSnapshotOfWebPageAtURL:(NSURL *)url completionBlock:(void (^)(NSImage *))block;<br />
    {<br />
        MWWebSnapshot *instance = [[self alloc] _initWithCompletionBlock:block];<br />
        [instance _beginDownloadFromURL:url];<br />
        [instance autorelease];<br />
    }<br />
    <br />
    <br />
    - (id)_initWithCompletionBlock:(void (^)(NSImage *))block;<br />
    {<br />
        self = [super init];<br />
        if (self &#33;= nil)<br />
        {<br />
    	    completionBlock = [block copy];<br />
    		<br />
    	    webView = [[WebView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 1000.0, 1000.0)<br />
    											   frameName:nil<br />
    											   groupName:nil];<br />
    	    [webView setFrameLoadDelegate:self];<br />
        }<br />
        return self;<br />
    }<br />
    <br />
    <br />
    - (void)_beginDownloadFromURL:(NSURL *)url;<br />
    {<br />
        [self retain];<br />
        [webView setMainFrameURL:[url absoluteString]];<br />
    }<br />
    <br />
    <br />
    - (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame<br />
    {<br />
        if (frame &#33;= [webView mainFrame])<br />
        {<br />
    	    return;<br />
        }<br />
    	<br />
        NSView *webFrameViewDocView = [[[webView mainFrame] frameView] documentView];<br />
        NSRect cacheRect = [webFrameViewDocView bounds];<br />
    	<br />
        NSBitmapImageRep *bitmapRep = [webFrameViewDocView bitmapImageRepForCachingDisplayInRect:cacheRect];<br />
        [webFrameViewDocView cacheDisplayInRect:cacheRect toBitmapImageRep:bitmapRep];<br />
    	<br />
        NSSize imgSize = cacheRect.size;<br />
        if (imgSize.height &gt; imgSize.width)<br />
        {<br />
    	    imgSize.height = imgSize.width;<br />
        }<br />
    	<br />
        NSRect srcRect = NSZeroRect;<br />
        srcRect.size = imgSize;<br />
        srcRect.origin.y = cacheRect.size.height - imgSize.height;<br />
    	<br />
        NSRect destRect = NSZeroRect;<br />
        destRect.size = imgSize;<br />
    	<br />
        NSImage *webImage = [[[NSImage alloc] initWithSize:imgSize] autorelease];<br />
        [webImage lockFocus];<br />
        [bitmapRep drawInRect:destRect<br />
    					 fromRect:srcRect<br />
    				    operation:NSCompositeCopy<br />
    					 fraction:1.0<br />
    			   respectFlipped:YES<br />
    					    hints:nil];<br />
        [webImage unlockFocus];<br />
    	<br />
        NSSize defaultDisplaySize;<br />
        defaultDisplaySize.height = 64.0 * (imgSize.height / imgSize.width);<br />
        defaultDisplaySize.width = 64.0;<br />
        [webImage setSize:defaultDisplaySize];<br />
    	<br />
        completionBlock(webImage);<br />
    	<br />
        [self autorelease];<br />
    }<br />
    <br />
    <br />
    - (void)dealloc<br />
    {<br />
        [completionBlock release];<br />
        [webView release];<br />
    	<br />
        [super dealloc];<br />
    }<br />
    <br />
    @end<br />
    
  • Hello,

    J'avais posté ceci il y a quelques temps. Si ça peut aider...
  • Merci pour vos réponse image/smile.png' class='bbc_emoticon' alt=':)' />

    Le problème reste entier mais je ne désespère pas.
  • Une petite question, tu cherche à  sauvegarder la capture dans un NSImage ? Tu souhaites une capture de toute la page web ou seulement la frame visible à  l'écran ?
  • Je pense que la solution est de vérifier que le sender à  l'origine de l'appel du delegate est bien la main frame, car si la page web dispose de plusieurs sous frames, dès qu'une des frames aura fini d'être chargé, ta méthode seras appelée et donc le résultat ne contiendras que la sous frame chargée. Je viens de tester et ça fonctionne nickel.


    <br />
    - (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame{<br />
    	if (frame == [sender mainFrame]) {<br />
    		// Get the full web page frame<br />
    		NSRect fullFrameRect = [[frame.frameView documentView] frame];<br />
    		// Cache bitmap<br />
    		NSBitmapImageRep *bitmapRepRight = [frame.frameView bitmapImageRepForCachingDisplayInRect:fullFrameRect];<br />
    		[[frame.frameView documentView] cacheDisplayInRect:fullFrameRect toBitmapImageRep:bitmapRepRight];<br />
    		// Save to png file<br />
    		NSData *data = [bitmapRepRight representationUsingType:NSPNGFileType properties:nil];<br />
    		[data writeToFile: @&quot;/Users/Greg/Desktop/webScreen.png&quot; atomically:NO];<br />
    	}<br />
    }<br />
    
Connectez-vous ou Inscrivez-vous pour répondre.