我对图像处理非常陌生。我必须在我的 iPhone 应用程序项目中实现色调效果。因此,我需要改变UIImage
. 请为此提供任何示例代码或教程链接。
提前致谢
我对图像处理非常陌生。我必须在我的 iPhone 应用程序项目中实现色调效果。因此,我需要改变UIImage
. 请为此提供任何示例代码或教程链接。
提前致谢
首先,您需要决定是使图像成为固定的色调,还是旋转现有的色调。两者的示例如下所示。
可以使用标准绘图工具修复色调 - 只需确保将混合模式设置为kCGBlendModeHue
,并使用适当的色调进行绘制。这源自 Nitish 的解决方案,尽管我发现制作saturation
小于的1.0
结果不一致。这种方法确实允许改变 alpha,但对于 100% 以外的真实饱和度,您可能需要进行第二轮绘图。
- (UIImage*) imageWithImage:(UIImage*) source fixedHue:(CGFloat) hue alpha:(CGFloat) alpha;
// Note: the hue input ranges from 0.0 to 1.0, both red. Values outside this range will be clamped to 0.0 or 1.0.
{
// Find the image dimensions.
CGSize imageSize = [source size];
CGRect imageExtent = CGRectMake(0,0,imageSize.width,imageSize.height);
// Create a context containing the image.
UIGraphicsBeginImageContext(imageSize);
CGContextRef context = UIGraphicsGetCurrentContext();
[source drawAtPoint:CGPointMake(0,0)];
// Draw the hue on top of the image.
CGContextSetBlendMode(context, kCGBlendModeHue);
[[UIColor colorWithHue:hue saturation:1.0 brightness:1 alpha:alpha] set];
UIBezierPath *imagePath = [UIBezierPath bezierPathWithRect:imageExtent];
[imagePath fill];
// Retrieve the new image.
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}
要旋转色调,您需要 Core Image 滤镜。下面的代码将 UIImage 转换为 CIImage,然后将结果转换回 UIImage 进行显示。根据您的图像的来源,您可以避免这些步骤中的一个或两个。
方便的是,Core Image Programming Guide: Using Core Image Filters中的第一个示例使用了 CIHueAdjust 过滤器。
// #import <CoreImage/CoreImage.h>
// Partially from https://developer.apple.com/library/mac/#documentation/graphicsimaging/conceptual/CoreImaging/ci_tasks/ci_tasks.html
- (UIImage*) imageWithImage:(UIImage*) source rotatedByHue:(CGFloat) deltaHueRadians;
{
// Create a Core Image version of the image.
CIImage *sourceCore = [CIImage imageWithCGImage:[source CGImage]];
// Apply a CIHueAdjust filter
CIFilter *hueAdjust = [CIFilter filterWithName:@"CIHueAdjust"];
[hueAdjust setDefaults];
[hueAdjust setValue: sourceCore forKey: @"inputImage"];
[hueAdjust setValue: [NSNumber numberWithFloat: deltaHueRadians] forKey: @"inputAngle"];
CIImage *resultCore = [hueAdjust valueForKey: @"outputImage"];
// Convert the filter output back into a UIImage.
// This section from http://stackoverflow.com/a/7797578/1318452
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef resultRef = [context createCGImage:resultCore fromRect:[resultCore extent]];
UIImage *result = [UIImage imageWithCGImage:resultRef];
CGImageRelease(resultRef);
return result;
}
- (void) changeToHue:(float)hue saturation:(float)saturation {
UIGraphicsBeginImageContext(self.bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
UIView *hueBlend = [[UIView alloc] initWithFrame:self.bounds];
hueBlend.backgroundColor = [UIColor colorWithHue:hue saturation:saturation brightness:1 alpha:1];
CGContextDrawImage(context, self.bounds, self.image.CGImage);
CGContextSetBlendMode(context, kCGBlendModeHue);
[hueBlend.layer renderInContext:context];
self.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
在 Apple 的 Swift 博客中,我遇到了这个照片过滤应用教程:https ://developer.apple.com/swift/blog/?id=16
以下是编辑的示例代码,用于创建一个包含的方法,该方法返回一个应用了随机色调的 UIImage。
func applyHue(source: UIImage) -> UIImage {
// Create a place to render the filtered image
let context = CIContext(options: nil)
// Create an image to filter
let inputImage = CIImage(image: source)
// Create a random color to pass to a filter
let randomColor = [kCIInputAngleKey: (Double(arc4random_uniform(314)) / 100)]
// Apply a filter to the image
let filteredImage = inputImage!.imageByApplyingFilter("CIHueAdjust", withInputParameters: randomColor)
// Render the filtered image
let renderedImage = context.createCGImage(filteredImage, fromRect: filteredImage.extent)
// Return a UIImage
return UIImage(CGImage: renderedImage)
}
上面 Dondragmer 的旋转代码的 Swift 版本
// Convert the filter output back into a UIImage.
// This section from http://stackoverflow.com/a/7797578/1318452
func imageWithImage(source: UIImage, rotatedByHue: CGFloat) -> UIImage {
// Create a Core Image version of the image.
let sourceCore = CIImage(CGImage: source.CGImage)
// Apply a CIHueAdjust filter
let hueAdjust = CIFilter(name: "CIHueAdjust")
hueAdjust.setDefaults()
hueAdjust.setValue(sourceCore, forKey: "inputImage")
hueAdjust.setValue(CGFloat(rotatedByHue), forKey: "inputAngle")
let resultCore = hueAdjust.valueForKey("outputImage") as CIImage!
let context = CIContext(options: nil)
let resultRef = context.createCGImage(resultCore, fromRect: resultCore!.extent())
let result = UIImage(CGImage: resultRef)
return result!
}
以 Dondragmer 的出色固定色调示例为起点。这是我的修改,以解决透明区域设置为相同色调的问题。
- (UIImage*) imageWithImage:(NSString *)name fixedHue:(CGFloat) hue alpha:(CGFloat) alpha;
// Note: the hue input ranges from 0.0 to 1.0, both red. Values outside this range will be clamped to 0.0 or 1.0.
{
UIImage *source = [UIImage imageNamed:name];
// Find the image dimensions.
CGSize imageSize = [source size];
CGRect imageExtent = CGRectMake(0,0,imageSize.width,imageSize.height);
// Create a context containing the image.
UIGraphicsBeginImageContext(imageSize);
CGContextRef context = UIGraphicsGetCurrentContext();
[source drawAtPoint:CGPointMake(0,0)];
// Setup a clip region using the image
CGContextSaveGState(context);
CGContextTranslateCTM(context, 0, source.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextClipToMask(context, imageExtent, source.CGImage);
//[[UIColor colorWithHue:hue saturation:1.0 brightness:1 alpha:alpha] set];
CGContextFillRect(context, imageExtent);
// Draw the hue on top of the image.
CGContextDrawImage(context, imageExtent, source.CGImage);
CGContextSetBlendMode(context, kCGBlendModeHue);
[[UIColor colorWithHue:hue saturation:1.0 brightness:1 alpha:alpha] set];
UIBezierPath *imagePath = [UIBezierPath bezierPathWithRect:imageExtent];
[imagePath fill];
CGContextRestoreGState(context); // remove clip region
// Retrieve the new image.
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}
谢谢:
对于从@JonLoard 更新的 Swift 5.0
func changeHue(_ image: UIImage, hueValue:CGFloat)->UIImage?{
if let sourceCGImage = image.cgImage{
let sourceCore = CIImage(cgImage: sourceCGImage)
// Apply a CIHueAdjust filter
let hueAdjust = CIFilter(name: "CIHueAdjust")
hueAdjust?.setDefaults()
hueAdjust?.setValue(sourceCore, forKey: "inputImage")
hueAdjust?.setValue(CGFloat(hueValue), forKey: "inputAngle")
if let resultCore = hueAdjust?.value(forKey: "outputImage") as? CIImage{
let context = CIContext(options: nil)
if let resultRef = context.createCGImage(resultCore, from: resultCore.extent){
let result = UIImage(cgImage: resultRef,scale: 1,orientation: image.imageOrientation)
return result
}
}
}
return image
}