Визуализация UIWebView в ImageContext - PullRequest
9 голосов
/ 22 января 2009

Я пытаюсь захватить содержимое UIWebView, включая то, что невидимо для пользователя. то есть вся веб-страница, хотя пользователь только смотрит сверху.

Оглядываясь вокруг, я обнаружил, что лучший способ захватить UIView - это извлечь его слой и использовать renderInContext.

Тем не менее, UIWebView, похоже, использует свою собственную реализацию CALayer, которая во многом похожа на CATiledLayer, хотя все еще утверждает, что является стандартным CALayer. Когда я вызываю renderInContext, я получаю только одну часть веб-страницы, до 940 пикселей вниз, в отличие от всей страницы.

Кто-нибудь получил какие-либо идеи о том, как: заставить UIWebView прокрутить вниз еще на 940 пикселей (очевидно, это далеко от идеала) или сказать любому типу CALayer, что он поддерживает WebView для отображения всего своего контента, когда я его спрашиваю к.

Приветствия

РЕДАКТИРОВАТЬ: Я должен добавить, что в настоящее время изменить рамку веб-просмотра, чтобы соответствовать размеру страницы, полученной с помощью JavaScript.

Ответы [ 6 ]

9 голосов
/ 05 августа 2011

Я выпустил приложение ( Web2Pic ), которое делает это, и, пожалуйста, поверьте мне, UIGraphicsBeginImageContext (webView.frame.size); ничего не могу сделать, кроме как получить маленькое изображение из видимой области в нашем UIWebView; - (

Правильный путь немного сложен, но он просто работает:

1.Используйте JavaScript в нашем UIWebView для получения следующих значений с плавающей запятой:

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

2. Теперь мы можем «разрезать» всю страницу на десятки маленьких кусочков размером с UIWebView. Затем мы можем захватить все маленькие кусочки по отдельности и сохранить их в нашем кеше. Я реализовал это путем вычисления смещений страниц и использую UIGraphicsBeginImageContext (webView.frame.size); , чтобы получить массив изображений. Кроме того, вы должны кешировать массив изображений в файловую систему, иначе приложение в конечном итоге вылетит!

3. Когда мы наконец получили все маленькие кусочки, мы можем начать контекст с полным разрешением: UIGraphicsBeginImageContext (CGSizeMake (document.body.scrollWidth, document.body.scrollHeight));

4.Рендерит каждое маленькое изображение в большой контекст на основе координат. И будьте осторожны с углами , последнее изображение в каждой строке / строке может быть не полным изображением.

5. Остался еще один шаг: сохранение большого изображения. Не сохраняйте его в фотоальбоме , поскольку iOS автоматически урезает разрешение изображений в альбоме. Вместо этого мы можем сохранить его в файловой системе и включить поддержку приложения iTunes File Share , или даже написать простой менеджер фотографий в приложении.

Надеюсь, это поможет; -)

Ичао Пик Цзи

2 голосов
/ 07 августа 2013

Установите высоту webview равную contentsize из scrollview из 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 голос
/ 19 февраля 2014

Изменение размера Webview - это способ, которым я решил это. Если вы хотите получить увеличенное изображение с большим количеством деталей, вам просто нужно увеличить его, прежде чем вызывать этот метод. Помните, что большие размеры могут повлиять на производительность.

- (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;

}

1 голос
/ 23 января 2009

Просто чтобы ответить на один из моих вопросов, вы можете прокрутить представление с помощью javascript.

Таким образом, вы используете stringByEvaluatingJavaScriptFromString: с javascript window.scrollTo(0,%i);, где% i - это место, куда вы хотите перейти. Вы также можете использовать scrollY для получения текущего значения прокрутки.

1 голос
/ 23 января 2009

Мне кажется, что UIWebView рендерится по требованию (посмотрите на шахматную доску, когда вы быстро прокрутите вниз на большой странице), так что в части слоя ниже того, что вы можете достичь, не будет ничего, пока пользователь не прокрутит вниз там. Слой не сможет записать то, чего у него нет, поэтому я не думаю, что вы сможете охватить всю область.

Что касается прокрутки, то не существует каких-либо очевидных открытых API-методов, о которых я мог бы подумать, чтобы сдвинуть их вниз. Кажется, что веб-представление содержит UIScrollView или что-то подобное, к которому вы могли бы попытаться обратиться, пройдя иерархию представления и используя его scrollRectToVisible: animated:, но это не похоже на хорошее долгосрочное решение.

0 голосов
/ 04 февраля 2009

Все UIViews имеют ограничение по размеру 1024x1024, поэтому вам, вероятно, придется программно прокручивать, захватывать страницу по частям и каким-то образом соединять их вместе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...