iphone - example - wkwebview ios
Presentar un UIWebView en un ImageContext (6)
Estoy tratando de capturar el contenido de una UIWebView que incluye lo que no es visible para el usuario. es decir, toda la página web aunque el usuario solo esté mirando hacia arriba.
Al mirar a mi 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 ha tenido alguna idea sobre cómo: forzar a UIWebView a desplazarse hacia abajo 940px (obviamente eso está lejos de ser ideal) o decirle a cualquier raza de CALayer que está respaldando WebView para renderizar todo su contenido cuando se lo pida.
Aclamaciones
EDITAR: Debo añadir que actualmente cambia el marco de la vista web para que se ajuste al tamaño de la página recuperada mediante javascript.
He lanzado una aplicación ( Web2Pic ) haciendo eso, y por favor confíen en mí ese UIGraphicsBeginImageContext (webView.frame.size); no puede hacer nada excepto obtener una imagen pequeña del área visible en nuestra UIWebView ;-(
El camino correcto es un poco complejo, pero simplemente funciona:
1.Utilice JavaScript en nuestra UIWebView para obtener estos valores flotantes:
//Whole page size in HTML coordinate
document.body.scrollWidth
document.body.scrollHeight
//UIWebView visible size in HTML coordinate
window.innerWidth
window.innerHeight
2. Ahora podemos ''cortar'' toda la página en docenas de pequeñas piezas del tamaño de UIWebView. Entonces podemos capturar cada pequeña pieza individualmente y guardarla en nuestro Caché. Implementé esto calculando desplazamientos de página y uso UIGraphicsBeginImageContext (webView.frame.size); para obtener una variedad de imágenes. Además, debe almacenar en caché la matriz de imágenes en el sistema de archivos, ¡o la aplicación eventualmente se bloqueará!
3. Cuando finalmente obtengamos todas las piezas pequeñas, podemos comenzar un contexto de resolución completa: UIGraphicsBeginImageContext (CGSizeMake (document.body.scrollWidth, document.body.scrollHeight));
4.Engrane cada imagen pequeña en el contexto grande basado en 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 , porque iOS reducirá automáticamente la resolución de las imágenes en el álbum. En cambio, podemos guardarlo en el sistema de archivos y habilitar la compatibilidad de iTunes File Share de la aplicación, o incluso escribir un simple administrador de fotos en la aplicación.
Espero que estos puedan ayudar ;-)
Yichao Peak Ji
Me parece que los renders de UIWebView a pedido (observe el tablero de ajedrez mientras se desplaza hacia abajo rápidamente en una página grande), de modo que no habrá nada en la parte de la capa por debajo de lo que puede alcanzar hasta que el usuario se desplace. 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 evidente que pueda pensar para 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.
Solo para responder a una de mis preguntas, puede desplazar la vista usando javascript.
Entonces usas 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.
Todas las UIView tienen un límite de tamaño de 1024x1024, por lo que es probable que haya desplazado de forma programática, capture la página en trozos y, de alguna forma, las haya unido.
Establezca el alto de la vista webview
igual al contentsize
de la scrollview
de webview
de la vista 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;
}
Cambiar el tamaño de la vista web es la forma en que lo resolví. 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;
}