Swift: обрезка скриншота

у меня есть скриншот всего экрана,screenshot, сгенерированный с помощью следующего:

let layer = UIApplication.sharedApplication().keyWindow!.layer
let scale = UIScreen.mainScreen().scale
UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);

layer.renderInContext(UIGraphicsGetCurrentContext())
let screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

Я хотел бы обрезать его так, чтобы панель вкладок не была включена, и я попытался использовать следующий код:

let crop = CGRectMake(0, 0, //"start" at the upper-left corner
self.view.bounds.width, //include half the width of the whole screen
self.view.bounds.height + self.navigationController!.navigationBar.frame.height) //include the height of the navigationBar and the height of view

let cgImage = CGImageCreateWithImageInRect(screenshot.CGImage, crop)
let image: UIImage = UIImage(CGImage: cgImage)!

этот код приводит к image показывает только небольшую часть экрана, прямоугольник, начинающийся в верхнем левом углу экрана (0, 0) и простирающийся вправо менее чем на половину ширины экрана, а затем вниз менее чем на половину высоты экрана. кино. Я хотел бы, однако, чтобы он включал весь экран, за исключением области, занятой панелью вкладок. Есть ли такой способ обрезать его?

4 ответов


по этому

новое изображение создается
1) регулировка rect к интегральным границам, вызвав CGRectIntegral;
2) пересечение результата прямоугольником с началом координат (0, 0) и размером равно размеру image;
3) ссылаться на пикселы внутри приводя прямоугольник, обрабатывая первого пикселя данных изображения в качестве источника изображения.
Если получившийся прямоугольник пустой прямоугольник, эта функция возвращает НОЛЬ.

если W и H-ширина и высота изображения соответственно, то точка (0,0) соответствует первому пикселю данных изображения; точка (W-1, 0) - последний пиксель первой строки данных изображения; (0, H-1) является первым пикселом последней строки данных изображения; и (W-1, H - 1) является последний пиксель последней строки данных изображения.

вам нужно будет иметь функцию обрезки, как это. Вам может понадобиться отрегулируйте расчет bottomBarHeight

func takeScreenshot(sender: AnyObject) {
    let layer = UIApplication.sharedApplication().keyWindow!.layer
    let scale = UIScreen.mainScreen().scale
    UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);

    layer.renderInContext(UIGraphicsGetCurrentContext())
    let screenshot = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    let croppedImage = self.cropImage(screenshot)
}

func cropImage(screenshot: UIImage) -> UIImage {
    let scale = screenshot.scale
    let imgSize = screenshot.size
    let screenHeight = UIScreen.mainScreen().applicationFrame.height
    let bound = self.view.bounds.height
    let navHeight = self.navigationController!.navigationBar.frame.height
    let bottomBarHeight = screenHeight - navHeight - bound
    let crop = CGRectMake(0, 0, //"start" at the upper-left corner
        (imgSize.width - 1) * scale, //include half the width of the whole screen
        (imgSize.height - bottomBarHeight - 1) * scale) //include the height of the navigationBar and the height of view

    let cgImage = CGImageCreateWithImageInRect(screenshot.CGImage, crop)
    let image: UIImage = UIImage(CGImage: cgImage)!
    return image
}

Свифт:

let contextImage: UIImage = <<screenshot>>!
let cropRect: CGRect = CGRectMake(x, y, width, height)
let imageRef: CGImageRef = CGImageCreateWithImageInRect(contextImage.CGImage, cropRect)
let image: UIImage = UIImage(CGImage: imageRef, scale: originalImage.scale, orientation: originalImage.imageOrientation)!

obj-c:

UIImage *image = <<screenshot>>;

CGRect croprect = CGRectMake(0, 0,
self.view.bounds.width,
self.view.bounds.height + self.navigationController!.navigationBar.frame.height));

// Draw new image in current graphics context
CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], croprect);

// Create new cropped UIImage
UIImage *croppedImage = [UIImage imageWithCGImage:imageRef];

у вас есть два варианта : Во-первых, вы можете сделать снимок экрана с помощью UIApplication.sharedApplication().keyWindow тогда мы будем иметь это:

    UIGraphicsBeginImageContext(UIApplication.sharedApplication().keyWindow!.bounds.size)
    UIApplication.sharedApplication().keyWindow!.layer.renderInContext(UIGraphicsGetCurrentContext())
    let screenshot = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

Итак, вам придется обрезать изображение следующим образом:

    let yPosition = self.navigationController!.navigationBar.frame.height + UIApplication.sharedApplication().statusBarFrame.size.height
    let crop = CGRectMake(0, yPosition,
            self.view.bounds.width, 
            self.view.bounds.height)
    let cgImage = CGImageCreateWithImageInRect(screenshot.CGImage, crop)
    let image: UIImage = UIImage(CGImage: cgImage)!

второй вариант состоит в том, чтобы сделать скриншот непосредственно из вашего представления, как это:

    UIGraphicsBeginImageContext(self.view!.bounds.size)
    self.view!.layer.renderInContext(UIGraphicsGetCurrentContext())
    let screenshot = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

в этом случае вам не нужно обрезать панель навигации.

Это пример кода на github https://github.com/gazolla/crop


Я думаю, ваш урожай CGRect - это неправильно.

let crop = CGRectMake(0,
                      0,
                      self.view.frame.size.width,
                      self.view.frame.size.height + self.navigationController!.navigationBar.frame.height - self.tabBar.frame.size.height
                     )

X: 0 и Y: 0 - начните с 0, 0 соответственно.

Width: захватите всю ширину вида

высота: высота всего вида плюс высота UINavigationBar минус высота UITabBar.