英文:
Change tintcolor image view using kingfihser in swift
问题
我有一个水平的集合视图,所以当选择特定的单元格时会改变图像视图的颜色,问题是当选择图像时,图像的色调颜色成功改变,但某些图像的色调颜色不会按照正确的行为显示为背景颜色在图像上。
这是用于更改图像色调颜色的函数:
func imageWithColor(color1: UIColor) -> UIImage {
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
color1.setFill()
let context = UIGraphicsGetCurrentContext()! as CGContext
context.translateBy(x: 0, y: self.size.height)
context.scaleBy(x: 1.0, y: -1.0);
context.setBlendMode(CGBlendMode.normal)
let rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
context.clip(to: rect, mask: self.cgImage!)
context.fill(rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()! as UIImage
UIGraphicsEndImageContext()
return newImage
}
使用Kingfisher显示图像:
imageProduct.kf.setImage(with: URL(string: "imageurl"), placeholder: nil) { result in
self.imageProduct.image = self.categoryImg.image?.imageWithColor(color1: UIColor.green)
}
必须成功更改从URL读取的任何图像的色调颜色(这是添加色调颜色时的问题图像的屏幕截图:https://freeimage.host/i/H4nx1s9)。
英文:
I have a horizontal collection view so when selecting the specific cell will change the color of the image view, the problem is when selecting an image tint color changes successfully on images, and some image's tint color does not work with the right behavior display as the background color on the image.
this is the function to change tint color of image
func imageWithColor(color1: UIColor) -> UIImage {
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
color1.setFill()
let context = UIGraphicsGetCurrentContext()! as CGContext
context.translateBy(x: 0, y: self.size.height)
context.scaleBy(x: 1.0, y: -1.0);
context.setBlendMode(CGBlendMode.normal)
let rect = CGRectMake(0, 0, self.size.width, self.size.height) as CGRect
context.clip(to: rect, mask: self.cgImage!)
context.fill(rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()! as UIImage
UIGraphicsEndImageContext()
return newImage
}
display image using kingfihser
` imageProduct.kf.setImage(with: URL(string:"imageurl"), placeholder: nil) { result in
self.imageProduct.image = self.categoryImg.image?.imageWithColor(color1: UIColor.green)
}`
The tint color must be changed successfully on any image read from url (this is screenshot from issue image when add tint color https://freeimage.host/i/H4nx1s9).
答案1
得分: 1
这里的问题似乎与如何应用色彩渲染到包含 alpha 通道(透明度)的图像有关。如果图像具有 alpha 通道,那么当应用色彩渲染时,可能不会按预期应用,可能会在图像上显示背景颜色。
一种方法可以是检查图像是否具有 alpha 通道并以不同方式处理它。然而,在您的情况下,最快的解决方案可能是使用 UIImage
的 renderingMode
属性,该属性控制图像的绘制方式。您可以将其设置为.alwaysTemplate
,这将使图像被视为用于与 tintColor
结合使用以创建最终彩色图像的模板。
以下是如何更改您的代码:
func imageWithColor(color1: UIColor) -> UIImage {
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
color1.setFill()
let context = UIGraphicsGetCurrentContext()! as CGContext
context.translateBy(x: 0, y: self.size.height)
context.scaleBy(x: 1.0, y: -1.0);
context.setBlendMode(CGBlendMode.normal)
let rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
context.clip(to: rect, mask: self.cgImage!)
context.fill(rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()! as UIImage
UIGraphicsEndImageContext()
return newImage.withRenderingMode(.alwaysTemplate) // 添加这一行
}
imageProduct.kf.setImage(with: URL(string: "imageurl"), placeholder: nil) { result in
switch result {
case .success(let value):
let image = value.image.imageWithColor(color1: .green)
DispatchQueue.main.async {
self.imageProduct.image = image
self.imageProduct.tintColor = .green
}
case .failure(let error):
print("Error: \(error)") // 处理错误
}
}
在上面的代码中,我们在返回图像之前将图像的 renderingMode
设置为 .alwaysTemplate
。在成功使用 Kingfisher 获取图像后,我们将 imageWithColor 函数应用于它,然后将该图像设置为 imageProduct
imageView,并最终将 imageView
的 tintColor
设置为所需的颜色。请注意,UI 更新应在主线程上执行,因此使用了 DispatchQueue.main.async
。
英文:
The issue here seems to be related to how tint color is applied to the images that contain an alpha channel (transparency). If an image has an alpha channel, then when the tint color is applied, it might not be applied as expected and could be showing the background color on the image.
One approach could be to check if the image has an alpha channel and handle it differently. However, in your case, the quickest solution could be to use the renderingMode
property of UIImage
which controls how the image is drawn. You can set it to .alwaysTemplate
which treats the image as a template for a mask that will be used in conjunction with the tintColor
to create the final colored image.
Here is how you can change your code:
func imageWithColor(color1: UIColor) -> UIImage {
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
color1.setFill()
let context = UIGraphicsGetCurrentContext()! as CGContext
context.translateBy(x: 0, y: self.size.height)
context.scaleBy(x: 1.0, y: -1.0);
context.setBlendMode(CGBlendMode.normal)
let rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
context.clip(to: rect, mask: self.cgImage!)
context.fill(rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()! as UIImage
UIGraphicsEndImageContext()
return newImage.withRenderingMode(.alwaysTemplate) // Add this line
}
imageProduct.kf.setImage(with: URL(string:"imageurl"), placeholder: nil) { result in
switch result {
case .success(let value):
let image = value.image.imageWithColor(color1: .green)
DispatchQueue.main.async {
self.imageProduct.image = image
self.imageProduct.tintColor = .green
}
case .failure(let error):
print("Error: \(error)") // handle error
}
}
In the code above, we set the renderingMode
of the image to .alwaysTemplate
before returning it. After the image is fetched successfully using Kingfisher, we apply the imageWithColor function to it, then set this image to the imageProduct
imageView, and finally set the tintColor
of the imageView
to the desired color. Please note that UI updates should be done on the main thread, hence the DispatchQueue.main.async
.
答案2
得分: 0
问题可能与图像的 alpha 通道或上下文中使用的混合模式有关。为了确保所有图像的行为一致,您可以修改您的 imageWithColor
函数如下所示:
func imageWithColor(color: UIColor) -> UIImage {
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
let context = UIGraphicsGetCurrentContext()!
let rect = CGRect(origin: .zero, size: self.size)
// 绘制图像
self.draw(in: rect)
// 应用色彩
context.setFillColor(color.cgColor)
context.setBlendMode(.sourceAtop)
context.fill(rect)
// 使用色彩创建新图像
let tintedImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return tintedImage
}
然后,您可以在 Kingfisher
的完成块中使用这个更新后的函数来设置图像的色彩:
imageProduct.kf.setImage(with: URL(string: "imageurl"), placeholder: nil) { result in
if case .success(let value) = result {
self.imageProduct.image = value.image.imageWithColor(color: UIColor.green)
}
}
希望这有所帮助。
英文:
The issue might be related to the alpha channel of the image or the blend mode used in the context. To ensure consistent behaviour across all images, you can modify your imageWithColor
like this
func imageWithColor(color: UIColor) -> UIImage {
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
let context = UIGraphicsGetCurrentContext()!
let rect = CGRect(origin: .zero, size: self.size)
// Draw the image
self.draw(in: rect)
// Apply tint color
context.setFillColor(color.cgColor)
context.setBlendMode(.sourceAtop)
context.fill(rect)
// Create a new image with the tint color
let tintedImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return tintedImage
}
You can then use this updated function to set the tint color of the image in your Kingfisher
completion block,
imageProduct.kf.setImage(with: URL(string: "imageurl"), placeholder: nil) { result in
if case .success(let value) = result {
self.imageProduct.image = value.image.imageWithColor(color: UIColor.green)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论