2009-01-22 15 views
9

Estoy tratando de capturar el contenido de un UIWebView incluyendo aquello que no es visible para el usuario. es decir, toda la página web aunque el usuario solo está mirando hacia arriba.Renderizar un UIWebView en un ImageContext

Mirando alrededor encontré que la mejor manera de capturar un UIView es recuperar su capa y usar renderInContext.

Sin embargo, UIWebView parece estar utilizando su propia implementación de CALayer que se comporta mucho más como CATiledLayer, aunque todavía pretende ser un CALayer estándar. Cuando llamo a renderInContext, solo obtengo una parte de la página web, hasta 940 px hacia abajo, a diferencia de toda la página.

¿Alguien tiene alguna idea sobre cómo forzar el UIWebView para desplazarse hacia abajo 940px (obviamente eso está lejos de ser ideal) o decirle a cualquier raza de CALayer que está respaldando el WebView para renderizar todo su contenido cuando pregunto a.

Saludos

EDIT: Debo añadir que actualmente cambiar el marco de la vista web para ajustarse al tamaño de la página recuperada a través de JavaScript.

Respuesta

1

Me parece que los renders UIWebView a pedido (observe el tablero mientras se desplaza hacia abajo rápidamente en una página grande), así no habrá nada en la parte de la capa debajo de lo que puede alcanzar hasta que el usuario se desplace ahí abajo. La capa no podrá escribir lo que no tiene, por lo que no creo que puedas capturar toda el área.

En lo que respecta al desplazamiento, no hay ningún método de API expuesta obvio que se me ocurra moverlo hacia abajo. La vista web parece albergar un UIScrollView o algo similar, al que podría intentar acceder atravesando la jerarquía de vista y usar su scrollRectToVisible: animated :, pero eso no parece una buena solución a largo plazo.

+0

Sí la vista web actúa como si tuviera un CATiledLayer, y sólo hace pedazos a la vez, si se trataba de un verdadero CATiledLayer que no sería tan malo como podría establecer el tamaño de la baldosa, pero desafortunadamente este no es el caso. Estoy jugando con el desplazamiento de la capa, pero tampoco me gusta. –

1

Solo para responder a una de mis preguntas, puede desplazar la vista mediante javascript.

Así que usa stringByEvaluatingJavaScriptFromString: con un javascript de window.scrollTo(0,%i);, donde% i es donde desea desplazarse. También puede usar scrollY para recuperar el valor de desplazamiento actual.

0

Todas las UIView tienen un límite de tamaño de 1024x1024, por lo que probablemente se haya desplazado de forma programática, capture la página en trozos y las haya unido de alguna forma.

9

me he lanzado una aplicación (Web2Pic) haciendo eso, y por favor créanme que UIGraphicsBeginImageContext (webView.frame.size); puede hacer nada más que obtener una imagen pequeña de la zona visible en nuestra UIWebView ;-(

La forma correcta es un poco complejo, pero solo funciona:

1.Utilice JavaScript en nuestra UIWebView para obtener estos valores de coma flotante:..

//Whole page size in HTML coordinate 
    document.body.scrollWidth 
    document.body.scrollHeight 
    //UIWebView visible size in HTML coordinate 
    window.innerWidth 
    window.innerHeight 

2.Now podemos 'corte' en la página entera de piezas pequeñas de tamaño UIWebView decenas Entonces podemos capturar todos los pequeños pedazos de forma individual y guardarlos en nuestra caché implementé esto por calcular ting page-offsets y use UIGraphicsBeginImageContext (webView.frame.size); para obtener una matriz de imágenes. Además, debe almacenar en caché la matriz de imágenes en el sistema de archivos, ¡o la aplicación finalmente se bloqueará!

3. Cuando finalmente conseguimos todas las piezas pequeñas, podemos comenzar un contexto de resolución completa: UIGraphicsBeginImageContext (CGSizeMake (document.body.scrollWidth, document.body.scrollHeight));

4.Realice cada imagen pequeña en el contexto grande en función de las coordenadas. Y tenga cuidado con las esquinas, la última imagen en cada línea/fila puede no ser una imagen completa.

5.Todavía queda un paso: guardar la imagen grande. No lo guarde en PhotoAlbum, ya que iOS reducirá automáticamente la resolución de las imágenes en el álbum. En su lugar, podemos guardarlo en el sistema de archivos y habilitar el soporte de la aplicación iTunes File Share, o incluso escribir un simple administrador de fotos en la aplicación.

Esperamos que estos pueden ayudar ;-)

Yichao Pico Ji

+1

En el paso 2, ¿tiene que desplazar manualmente la vista web? Si es así, ¿cómo haces esto? Como Dany Greg declaró en un comentario anterior? – vIceBerg

+2

@vIceBerg iOS4.x: use Javascript window.scrollTo (% i,% i); iOS5: UIWebView ahora tiene una subvista: scrollView, para que pueda desplazarse usando la propiedad de compensación de contenido. – PeakJi

+0

¿Cómo se implementa el paso 4? – Greg

2

Ajuste la altura de webview igual a la de contentsizescrollview de webview.

-(UIImage *)captureImage:(UIWebView *)webvw 
{ 
    webvw.frame=CGRectMake(webvw.frame.origin.x, webvw.frame.origin.y, webvw.frame.size.width, webvw.scrollView.contentSize.height); 
    UIGraphicsBeginImageContextWithOptions(webvw.frame.size, NO, 0.0f); 
    [webvw.layer renderInContext:UIGraphicsGetCurrentContext()]; 
    UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext(); 
    return screenshot; 
} 
1

Cambiar el tamaño de la vista web es la forma en que lo resolvió. Si desea una imagen más grande con más detalles, solo tiene que acercarse antes de llamar a este método. Tenga en cuenta que las grandes dimensiones podrían influir en el rendimiento.

- (UIImage*) imageFromWebview:(UIWebView*) webview{ 

//store the original framesize to put it back after the snapshot 
CGRect originalFrame = webview.frame; 

//get the width and height of webpage using js (you might need to use another call, this doesn't work always) 
int webViewHeight = [[webview stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight;"] integerValue]; 
int webViewWidth = [[webview stringByEvaluatingJavaScriptFromString:@"document.body.scrollWidth;"] integerValue]; 

//set the webview's frames to match the size of the page 
[webview setFrame:CGRectMake(0, 0, webViewWidth, webViewHeight)]; 

//make the snapshot 
UIGraphicsBeginImageContextWithOptions(webview.frame.size, false, 0.0); 
[webview.layer renderInContext:UIGraphicsGetCurrentContext()]; 
UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

//set the webview's frame to the original size 
[webview setFrame:originalFrame]; 

//and VOILA :) 
return image; 

}