Программно сделать снимок экрана определенной области
Как вы можете видеть в моем коде, я делаю снимок экрана и сохраняю его в фотоальбоме.
//for retina displays
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, [UIScreen mainScreen].scale);
} else {
UIGraphicsBeginImageContext(self.view.bounds.size);
}
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
В начале я использовал webview.size
вместо self.view.bounds.size
, и он работал правильно, потому что представление было расположено в 0/0
. Но теперь я сосредоточил WebView, но картинки начинаются с 0/0
для заданного размера.
Как настроить, чтобы скриншот начинался с другого location
(например, 300/150
) для заданного размера?
Или есть другой способ сделать снимок UIWebView
?
Ответы
Ответ 1
Я решил свою проблему, но не ответил на вопрос:
Я создал подкласс UIView
и переместил туда мой UIWebView
, так что он расположен 0/0 относительно подкласса. Затем используйте размер WebView:
UIGraphicsBeginImageContext(webview.frame.size);
и другой код сверху.
Теперь вы можете переместить подкласс в любое место, которое вы хотите.
Примечание. Если у вас есть метки, такие как метка даты/времени, вы должны их переместить или вы не увидите их на картинке.
Итак, создайте подкласс UIView
и переместите все IBOutlet
, которые вы хотите видны на фотографии там.
Вопрос остается открытым:
Можно ли сделать снимок определенной области экрана?
С уважением. $Ч @скалистый
Ответ 2
Вам нужно сделать два изменения, чтобы захватить только часть экрана:
- Создайте меньшее изображение - используйте размер прямоугольника, который вы хотите захватить.
- Переместите начало контекста, в котором вы рендерируете, на отрицательный x/y прямоугольника, который вы хотите захватить.
После этого вы просто визуализируете слой в контексте, как вы делали, и вы должны получить то, что ищете. Что-то вроде этого должно это сделать:
CGRect grabRect = CGRectMake(40,40,300,200);
//for retina displays
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
UIGraphicsBeginImageContextWithOptions(grabRect.size, NO, [UIScreen mainScreen].scale);
} else {
UIGraphicsBeginImageContext(grabRect.size);
}
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(ctx, -grabRect.origin.x, -grabRect.origin.y);
[self.view.layer renderInContext:ctx];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
Ответ 3
Я взял и протестировал ответ @escrafford выше, и получил его, чтобы он работал нормально. Я проверил его в контексте создания метода категорий в UIView, так что "grabRect" может быть параметризирован. Здесь этот код, как категория UIView, который возвращает вам UIImageView:
/**
Takes a screenshot of a UIView at a specific point and size, as denoted by
the provided croppingRect parameter. Returns a UIImageView of this cropped
region.
CREDIT: This is based on @escrafford answer at http://stackoverflow.com/a/15304222/535054
*/
- (UIImageView *)rp_screenshotImageViewWithCroppingRect:(CGRect)croppingRect {
// For dealing with Retina displays as well as non-Retina, we need to check
// the scale factor, if it is available. Note that we use the size of teh cropping Rect
// passed in, and not the size of the view we are taking a screenshot of.
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
UIGraphicsBeginImageContextWithOptions(croppingRect.size, YES, [UIScreen mainScreen].scale);
} else {
UIGraphicsBeginImageContext(croppingRect.size);
}
// Create a graphics context and translate it the view we want to crop so
// that even in grabbing (0,0), that origin point now represents the actual
// cropping origin desired:
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(ctx, -croppingRect.origin.x, -croppingRect.origin.y);
[self.layer renderInContext:ctx];
// Retrieve a UIImage from the current image context:
UIImage *snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Return the image in a UIImageView:
return [[UIImageView alloc] initWithImage:snapshotImage];
}
Ответ 4
- (void)drawRect:(CGRect)rect {
UIGraphicsBeginImageContext(self.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
}
Вы могли бы назвать это своим видом:]