UIImagePNGRпредставление и маскированные изображения - PullRequest
3 голосов
/ 16 ноября 2010
  1. I создал замаскированное изображение с помощью функции из блога 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 ]

3 голосов
/ 16 ноября 2010

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

0 голосов
/ 13 сентября 2013

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

Виновником и решением был 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
...