UIImagePNGR представление и маскированные изображения

  1. Я создал замаскированное изображение, используя функцию из блога iphone:

    UIImage * imgToSave = [self maskImage: [UIImage imageNamed: @ "pic.jpg"] withMask: [UIImage imageNamed: @ "sd-face-mask.png"]];

  2. Хорошо выглядит в UIImageView

    UIImageView *imgView = [[UIImageView alloc] initWithImage:imgToSave];
    imgView.center = CGPointMake(160.0f, 140.0f);
    [self.view addSubview:imgView];
    
  3. UIImagePNGR представляет для сохранения на диск:

    [UIImagePNGRepresentation (imgToSave) writeToFile: [self findUniqueSavePath] атомарно: ДА];

UIImagePNGRepresentation возвращает NSData изображения, которое выглядит по-другому.

На выходе получается обратная маска изображения. Область, вырезанная в приложении, теперь видна в файле. Область, которая была видна в приложении, теперь удалена. Видимость противоположна.

Моя маска предназначена для удаления всего, кроме области лица на картинке. UIImage выглядит прямо в приложении, но после сохранения его на диске файл выглядит наоборот. Лицо снято, но все остальное это есть.

Пожалуйста, дайте мне знать, если вы можете помочь!

2 ответа

Решение

У меня была точно такая же проблема, когда я сохранял файл, это был один из способов, но изображение, возвращенное в память, было совершенно противоположным.

Виновником и решением был UIImagePNGRepresentation(). Он исправляет изображение в приложении перед сохранением его на диск, поэтому я просто вставил эту функцию в качестве последнего шага в создании маскированного изображения и его возврате.

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

Наслаждаться.:)

// MyImageHelperObj.h

@interface MyImageHelperObj : NSObject

+ (UIImage *) createGrayScaleImage:(UIImage*)originalImage;
+ (UIImage *) createMaskedImageWithSize:(CGSize)newSize sourceImage:(UIImage *)sourceImage maskImage:(UIImage *)maskImage;

@end





// MyImageHelperObj.m

#import <QuartzCore/QuartzCore.h>
#import "MyImageHelperObj.h"


@implementation MyImageHelperObj


+ (UIImage *) createMaskedImageWithSize:(CGSize)newSize sourceImage:(UIImage *)sourceImage maskImage:(UIImage *)maskImage;
{
    // create image size rect
    CGRect newRect = CGRectZero;
    newRect.size = newSize;

    // draw source image
    UIGraphicsBeginImageContextWithOptions(newRect.size, NO, 0.0f);
    [sourceImage drawInRect:newRect];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();

    // draw mask image
    [maskImage drawInRect:newRect blendMode:kCGBlendModeNormal alpha:1.0f];
    maskImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    // create grayscale version of mask image to make the "image mask"
    UIImage *grayScaleMaskImage = [MyImageHelperObj createGrayScaleImage:maskImage];
    CGFloat width = CGImageGetWidth(grayScaleMaskImage.CGImage);
    CGFloat height = CGImageGetHeight(grayScaleMaskImage.CGImage);
    CGFloat bitsPerPixel = CGImageGetBitsPerPixel(grayScaleMaskImage.CGImage);
    CGFloat bytesPerRow = CGImageGetBytesPerRow(grayScaleMaskImage.CGImage);
    CGDataProviderRef providerRef = CGImageGetDataProvider(grayScaleMaskImage.CGImage);
    CGImageRef imageMask = CGImageMaskCreate(width, height, 8, bitsPerPixel, bytesPerRow, providerRef, NULL, false);

    CGImageRef maskedImage = CGImageCreateWithMask(newImage.CGImage, imageMask);
    CGImageRelease(imageMask);
    newImage = [UIImage imageWithCGImage:maskedImage];
    CGImageRelease(maskedImage);
    return [UIImage imageWithData:UIImagePNGRepresentation(newImage)];
}

+ (UIImage *) createGrayScaleImage:(UIImage*)originalImage;
{
    //create gray device colorspace.
    CGColorSpaceRef space = CGColorSpaceCreateDeviceGray();
    //create 8-bit bimap context without alpha channel.
    CGContextRef bitmapContext = CGBitmapContextCreate(NULL, originalImage.size.width, originalImage.size.height, 8, 0, space, kCGImageAlphaNone);
    CGColorSpaceRelease(space);
    //Draw image.
    CGRect bounds = CGRectMake(0.0, 0.0, originalImage.size.width, originalImage.size.height);
    CGContextDrawImage(bitmapContext, bounds, originalImage.CGImage);
    //Get image from bimap context.
    CGImageRef grayScaleImage = CGBitmapContextCreateImage(bitmapContext);
    CGContextRelease(bitmapContext);
    //image is inverted. UIImage inverts orientation while converting CGImage to UIImage.
    UIImage* image = [UIImage imageWithCGImage:grayScaleImage];
    CGImageRelease(grayScaleImage);
    return image;
}

@end

В кварце вы маскируете либо маской изображения (черные сквозные и белые блоки), либо обычным изображением (белые сквозные и черные блоки), что противоположно. Кажется, по какой-то причине сохранение рассматривает маску изображения как обычное изображение для маскировки. Одной из мыслей является рендеринг в растровый контекст, а затем создание изображения, которое будет сохранено из этого.

Другие вопросы по тегам