UIImage, созданный из CGImageRef, терпит неудачу с UIImagePNGRepresentation - PullRequest
13 голосов
/ 11 февраля 2010

Я использую следующий код для обрезки и создания нового UIImage из большего. Я изолировал проблему с помощью функции CGImageCreateWithImageInRect (), которая, кажется, не устанавливает какое-либо свойство CGImage так, как я хочу. :-) Проблема в том, что вызов функции UIImagePNGRepresentation () не может вернуть ноль.

CGImageRef origRef = [stillView.image CGImage];
CGImageRef cgCrop = CGImageCreateWithImageInRect( origRef, theRect);
UIImage *imgCrop = [UIImage imageWithCGImage:cgCrop];

...

NSData *data = UIImagePNGRepresentation ( imgCrop);

- ошибка libpng: в файл не записаны IDAT

Есть идеи, что может быть неправильным или альтернативным для обрезки прямоугольника из UIImage? Большое спасибо!

Ответы [ 4 ]

3 голосов
/ 17 марта 2011

У меня была такая же проблема, но только при тестировании совместимости на iOS 3.2. На 4.2 работает нормально.

В конце концов я нашел это http://www.hive05.com/2008/11/crop-an-image-using-the-iphone-sdk/, которое работает на обоих, хотя и более многословно!

Я преобразовал это в категорию на UIImage:

UIImage + Crop.h

@interface UIImage (Crop)
- (UIImage*) imageByCroppingToRect:(CGRect)rect;
@end

UIImage + Crop.m

@implementation UIImage (Crop)

- (UIImage*) imageByCroppingToRect:(CGRect)rect
{
    //create a context to do our clipping in
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    //create a rect with the size we want to crop the image to
    //the X and Y here are zero so we start at the beginning of our
    //newly created context
    CGRect clippedRect = CGRectMake(0, 0, rect.size.width, rect.size.height);
    CGContextClipToRect( currentContext, clippedRect);

    //create a rect equivalent to the full size of the image
    //offset the rect by the X and Y we want to start the crop
    //from in order to cut off anything before them
    CGRect drawRect = CGRectMake(rect.origin.x * -1,
                                 rect.origin.y * -1,
                                 self.size.width,
                                 self.size.height);

    //draw the image to our clipped context using our offset rect
    CGContextTranslateCTM(currentContext, 0.0, rect.size.height);
    CGContextScaleCTM(currentContext, 1.0, -1.0);
    CGContextDrawImage(currentContext, drawRect, self.CGImage);

    //pull the image from our cropped context
    UIImage *cropped = UIGraphicsGetImageFromCurrentImageContext();

    //pop the context to get back to the default
    UIGraphicsEndImageContext();

    //Note: this is autoreleased
    return cropped;
}


@end
1 голос
/ 09 июля 2010

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

CGImageRef image = [stillView.image CGImage];
CGRect cropZone;

size_t cWitdh = cropZone.size.width;
size_t cHeight = cropZone.size.height;
size_t bitsPerComponent = CGImageGetBitsPerComponent(image);
size_t bytesPerRow = CGImageGetBytesPerRow(image) / CGImageGetWidth(image) * cWidth;

//Now we build a Context with those dimensions.
CGContextRef context = CGBitmapContextCreate(nil, cWitdh, cHeight, bitsPerComponent, bytesPerRow, CGColorSpaceCreateDeviceRGB(), CGImageGetBitmapInfo(image));

CGContextDrawImage(context, cropZone, image);

CGImageRef result  = CGBitmapContextCreateImage(context);
UIImage * cropUIImage = [[UIImage alloc] initWithCGImage:tmp];

CGContextRelease(context);
CGImageRelease(mergeResult);
NSData * imgData = UIImagePNGRepresentation ( cropUIImage);

Надеюсь, это поможет.

1 голос
/ 11 февраля 2010

В PNG присутствуют различные фрагменты, некоторые из которых содержат информацию о палитре, некоторые фактические данные изображения и некоторую другую информацию, это очень интересный стандарт. Блок IDAT - это бит, который фактически содержит данные изображения. Если «IDAT записан в файл», то в libpng возникли проблемы с созданием PNG из входных данных.

Я не знаю точно, что такое ваш stillView.image, но что происходит, когда вы передаете свой код CGImageRef, который, безусловно, действителен? Каковы фактические значения в theRect? Если ваш theRect находится за пределами изображения, тогда cgCrop, который вы пытаетесь использовать для создания UIImage, может легко быть нулевым или не нулевым, но не содержит изображения или изображения с шириной и высотой 0, что не дает libpng ничего работать. с.

0 голосов
/ 26 мая 2012

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

UIImage *croppedImage = [self imageByCropping:yourImageView.image toRect:heredefineyourRect];

    CGSize size = CGSizeMake(croppedImage.size.height, croppedImage.size.width);
    UIGraphicsBeginImageContext(size);

    CGPoint pointImg1 = CGPointMake(0,0);
    [croppedImage drawAtPoint:pointImg1 ];

    [[UIImage imageNamed:yourImagenameDefine] drawInRect:CGRectMake(0,532, 150,80) ];//here define your Reactangle

    UIImage* result = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    croppedImage = result;
    yourCropImageView.image=croppedImage;
    [yourCropImageView.image retain];

надеюсь, это поможет вам ....:)

...