图像蒙版后保持正确的色调
Keeping right tints after image masking
我需要用不同颜色的蒙版以编程方式填充图像,我从我们的设计师那里得到了 photoshop 文件:
http://image.openlan.ru/images/83339350420766181806.png
除了遗漏的细节,我几乎完成了这个:
UIImage *mask = [UIImage imageNamed:@"mask.png"];
UIImage *image = [UIImage imageNamed:@"vehicle.png"];
mask = [image maskImage:image withMask:mask];
image = [image coloredImageWithColor:[UIColor blueColor]];
image = [image drawImage:mask inImage:image];
其中方法实现:
- (UIImage *) maskImage:(UIImage *)image withMask:(UIImage *)maskImage
{
CGImageRef maskRef = maskImage.CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef), NULL, false);
CGImageRef masked = CGImageCreateWithMask([image CGImage], mask);
UIImage *im = [UIImage imageWithCGImage:masked];
CGImageRelease(masked);
CGImageRelease(maskRef);
CGImageRelease(mask);
return im;
}
- (UIImage *) coloredImageWithColor:(UIColor *)color
{
UIGraphicsBeginImageContext(self.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, 0, self.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextSetBlendMode(context, kCGBlendModeDarken);
CGRect rect = (CGRect){ CGPointZero, self.size };
CGContextDrawImage(context, rect, self.CGImage);
CGContextClipToMask(context, rect, self.CGImage);
[color set];
CGContextFillRect(context, rect);
UIImage *coloredImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return coloredImage;
}
- (UIImage *) drawImage:(UIImage *)fgImage inImage:(UIImage *)bgImage
{
UIGraphicsBeginImageContextWithOptions(bgImage.size, FALSE, 0.0);
[bgImage drawInRect:(CGRect){ CGPointZero, bgImage.size }];
[fgImage drawInRect:(CGRect){ CGPointZero, fgImage.size }];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
我目前的结果是:
http://image.openlan.ru/images/34429534616655410787.png
我不认为如果我使用渐变,我会看到正确的结果。我现在不喜欢的是某些图像区域缺少色调。我在这里做错了什么?
受此启发post我最终实现了我的任务。
这是原始图像:
然后我给这张图画了一个遮罩,不要填充特殊区域:
下面是绘制这个的主要方法:
- (void) vehicleConfigure
{
NSString *vehicleName = @"sports.png";
UIImage *vehicleImage = [UIImage imageNamed:vehicleName];
vehicleName = [vehicleName stringByReplacingOccurrencesOfString:@".png" withString:@"-mask.png"];
UIImage *mask = [UIImage imageNamed:vehicleName];
mask = [vehicleImage applyingMask:mask];
vehicleImage = [vehicleImage coloredImageWithColor:RGB(30, 128, 255)];
vehicleImage = [vehicleImage drawMask:mask];
m_vehicleImageView.contentMode = UIViewContentModeScaleAspectFit;
m_vehicleImageView.image = vehicleImage;
}
我在哪里使用 UIImage
的类别和方法:
- (UIImage *) drawMask:(UIImage *)mask
{
UIGraphicsBeginImageContextWithOptions(self.size, FALSE, 0.0);
[self drawInRect:(CGRect){ CGPointZero, self.size }];
[mask drawInRect:(CGRect){ CGPointZero, mask.size }];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
- (UIImage *) applyingMask:(UIImage *)maskImage
{
CGImageRef maskRef = maskImage.CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef), NULL, false);
CGImageRef masked = CGImageCreateWithMask([self CGImage], mask);
UIImage *im = [UIImage imageWithCGImage:masked
scale:[[UIScreen mainScreen] scale]
orientation:UIImageOrientationUp];
// CGImageRelease(masked);
// CGImageRelease(maskRef);
// CGImageRelease(mask);
return im;
}
- (UIImage *) coloredImageWithColor:(UIColor *)color
{
UIGraphicsBeginImageContext(self.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, 0, self.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextSetBlendMode(context, kCGBlendModeColorBurn);
CGRect rect = (CGRect){ CGPointZero, self.size };
CGContextDrawImage(context, rect, self.CGImage);
CGContextClipToMask(context, rect, self.CGImage);
[color set];
CGContextFillRect(context, rect);
UIImage *coloredImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return coloredImage;
}
结果看起来:
我需要用不同颜色的蒙版以编程方式填充图像,我从我们的设计师那里得到了 photoshop 文件: http://image.openlan.ru/images/83339350420766181806.png
除了遗漏的细节,我几乎完成了这个:
UIImage *mask = [UIImage imageNamed:@"mask.png"];
UIImage *image = [UIImage imageNamed:@"vehicle.png"];
mask = [image maskImage:image withMask:mask];
image = [image coloredImageWithColor:[UIColor blueColor]];
image = [image drawImage:mask inImage:image];
其中方法实现:
- (UIImage *) maskImage:(UIImage *)image withMask:(UIImage *)maskImage
{
CGImageRef maskRef = maskImage.CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef), NULL, false);
CGImageRef masked = CGImageCreateWithMask([image CGImage], mask);
UIImage *im = [UIImage imageWithCGImage:masked];
CGImageRelease(masked);
CGImageRelease(maskRef);
CGImageRelease(mask);
return im;
}
- (UIImage *) coloredImageWithColor:(UIColor *)color
{
UIGraphicsBeginImageContext(self.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, 0, self.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextSetBlendMode(context, kCGBlendModeDarken);
CGRect rect = (CGRect){ CGPointZero, self.size };
CGContextDrawImage(context, rect, self.CGImage);
CGContextClipToMask(context, rect, self.CGImage);
[color set];
CGContextFillRect(context, rect);
UIImage *coloredImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return coloredImage;
}
- (UIImage *) drawImage:(UIImage *)fgImage inImage:(UIImage *)bgImage
{
UIGraphicsBeginImageContextWithOptions(bgImage.size, FALSE, 0.0);
[bgImage drawInRect:(CGRect){ CGPointZero, bgImage.size }];
[fgImage drawInRect:(CGRect){ CGPointZero, fgImage.size }];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
我目前的结果是: http://image.openlan.ru/images/34429534616655410787.png
我不认为如果我使用渐变,我会看到正确的结果。我现在不喜欢的是某些图像区域缺少色调。我在这里做错了什么?
受此启发post我最终实现了我的任务。
这是原始图像:
然后我给这张图画了一个遮罩,不要填充特殊区域:
下面是绘制这个的主要方法:
- (void) vehicleConfigure
{
NSString *vehicleName = @"sports.png";
UIImage *vehicleImage = [UIImage imageNamed:vehicleName];
vehicleName = [vehicleName stringByReplacingOccurrencesOfString:@".png" withString:@"-mask.png"];
UIImage *mask = [UIImage imageNamed:vehicleName];
mask = [vehicleImage applyingMask:mask];
vehicleImage = [vehicleImage coloredImageWithColor:RGB(30, 128, 255)];
vehicleImage = [vehicleImage drawMask:mask];
m_vehicleImageView.contentMode = UIViewContentModeScaleAspectFit;
m_vehicleImageView.image = vehicleImage;
}
我在哪里使用 UIImage
的类别和方法:
- (UIImage *) drawMask:(UIImage *)mask
{
UIGraphicsBeginImageContextWithOptions(self.size, FALSE, 0.0);
[self drawInRect:(CGRect){ CGPointZero, self.size }];
[mask drawInRect:(CGRect){ CGPointZero, mask.size }];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
- (UIImage *) applyingMask:(UIImage *)maskImage
{
CGImageRef maskRef = maskImage.CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef), NULL, false);
CGImageRef masked = CGImageCreateWithMask([self CGImage], mask);
UIImage *im = [UIImage imageWithCGImage:masked
scale:[[UIScreen mainScreen] scale]
orientation:UIImageOrientationUp];
// CGImageRelease(masked);
// CGImageRelease(maskRef);
// CGImageRelease(mask);
return im;
}
- (UIImage *) coloredImageWithColor:(UIColor *)color
{
UIGraphicsBeginImageContext(self.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, 0, self.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextSetBlendMode(context, kCGBlendModeColorBurn);
CGRect rect = (CGRect){ CGPointZero, self.size };
CGContextDrawImage(context, rect, self.CGImage);
CGContextClipToMask(context, rect, self.CGImage);
[color set];
CGContextFillRect(context, rect);
UIImage *coloredImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return coloredImage;
}
结果看起来: