C4 сохранение части изображения

Привет, я прошел пример сохранения изображений, а потом захотел сохранить только часть экрана. Мне удалось сохранить часть, начинающуюся в верхнем левом углу изображения, но на самом деле я хочу сохранить центр экрана. Магия сохранения только части изображения заключается в настройке графического контекста определенного размера, например:

 UIGraphicsBeginImageContextWithOptions(CGSizeMake(300, 300), YES, 5.0f);

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


person suMi    schedule 21.10.2013    source источник


Ответы (3)


Чтобы сделать это с объектами C4Image, вы можете изменить ответ incmiko, чтобы он выглядел следующим образом:

#import "C4Workspace.h"

@implementation C4WorkSpace{
    C4Image *image;
    C4Image *croppedImage;
}

-(void)setup {
    image=[C4Image imageNamed:@"C4Sky.png"];
    image.origin=CGPointMake(0, 20);

    croppedImage = [self cropImage:image toArea:CGRectMake(150,50,100,100)];
    croppedImage.origin = CGPointMake(20, 360);
    [self.canvas addObjects:@[image,croppedImage]];
}

-(C4Image *)cropImage:(C4Image *)originalImage toArea:(CGRect)rect{
    //grab the image scale
    CGFloat scale = originalImage.UIImage.scale;

    //begin an image context
    UIGraphicsBeginImageContextWithOptions(rect.size, NO, scale);

    //create a new context ref
    CGContextRef c = UIGraphicsGetCurrentContext();

    //shift BACKWARDS in both directions because this moves the image
    //the area to crop shifts INTO: (0, 0, rect.size.width, rect.size.height)
    CGContextTranslateCTM(c, -rect.origin.x, -rect.origin.y);

    //render the original image into the context
    [originalImage renderInContext:c];

    //grab a UIImage from the context
    UIImage *newUIImage = UIGraphicsGetImageFromCurrentImageContext();

    //end the image context
    UIGraphicsEndImageContext();

    //create a new C4Image
    C4Image *newImage = [C4Image imageWithUIImage:newUIImage];

    //return the new image
    return newImage;
}
@end

Помимо комментариев в коде, есть еще пара вещей, о которых нужно знать:

  1. «Область», которую вы обрезаете, всегда будет относиться к «изображению», которое вы обрезаете. Итак, если вы хотите обрезать {150,50} из изображения, а исходная точка изображения находится в {20,20}, тогда это будет ВЫГЛЯДИТЬ так, как будто вы обрезаете {170,70} с ХОЛСТА.

  2. Объект C4Image на самом деле имеет метод renderInContext:, поэтому вам не нужно делать это из слоя изображения.

  3. C4Image объектов обернуть UIImage объектов, поэтому мы создаем новый, используя UIImage, который мы получаем из текущего контекста

person C4 - Travis    schedule 22.10.2013

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

+ (UIImage*) getTheArea:(CGRect)area inView:(UIView*)view{

    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
        UIGraphicsBeginImageContextWithOptions(CGSizeMake(area.size.width, area.size.height), NO, [UIScreen mainScreen].scale);
    else
        UIGraphicsBeginImageContext(view.bounds.size);

    CGContextRef c = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(c, -area.origin.x, -area.origin.y);    // <-- shift everything up by 40px when drawing.
    [view.layer renderInContext:c];
    UIImage* thePrintScreen = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return thePrintScreen;
}

например, если вы хотите сделать принтскрин основного вида, в (100,50,100,100)

UIImage* image = [self getTheArea:CGRectMake(100,50,100,100) inView:view];
person incmiko    schedule 21.10.2013
comment
к чему относится ваше представление в UIImage* image = [self getTheArea:CGRectMake(100,50,100,100) inView:view]; ссылаться? Я использую C4, поэтому мне придется немного изменить код.... - person suMi; 21.10.2013
comment
вид - это тот вид, о котором вы хотите сделать скриншот, я не знаю C4, извините - person incmiko; 21.10.2013
comment
Да, это хороший ответ. CGContextTranslateCTM() - это то, что перемещает размер в правильную координату. - person C4 - Travis; 21.10.2013

небольшая модификация ответа Трэвиса делает его независимым от изображения, но зависящим от происхождения холста:

-(C4Image *)cropImage:(C4Image *)originalImage withOrigin:(CGPoint)origin toArea:(CGRect)rect{
    //grab the image scale
    CGFloat scale = originalImage.UIImage.scale;

    //begin an image context
    UIGraphicsBeginImageContextWithOptions(rect.size, NO, scale);

    //create a new context ref
    CGContextRef c = UIGraphicsGetCurrentContext();

    //shift BACKWARDS in both directions because this moves the image
    //the area to crop shifts INTO: (0, 0, rect.size.width, rect.size.height)
    CGContextTranslateCTM(c, origin.x-rect.origin.x, origin.y-rect.origin.y);

    //render the original image into the context
    [originalImage renderInContext:c];

    //grab a UIImage from the context
    UIImage *newUIImage = UIGraphicsGetImageFromCurrentImageContext();

    //end the image context
    UIGraphicsEndImageContext();

    //create a new C4Image
    C4Image *newImage = [C4Image imageWithUIImage:newUIImage];

    //return the new image
    return newImage;
}
person suMi    schedule 23.10.2013