gpt4 book ai didi

ios - 更改 UIImage 中的白色像素

转载 作者:搜寻专家 更新时间:2023-11-01 05:31:33 35 4
gpt4 key购买 nike

我有一个 UIImage,它是一个轮廓,一个是填充的,两者都是从 OpenCV 创建的,一个来自抓取,另一个来自结构化元素。

我的两张图片是这样的:

enter image description here

enter image description here

我试图更改轮廓图像中的所有白色像素,因为我想将两个图像合并在一起,所以我最终得到一个红色轮廓和中间的白色填充区域。我正在使用它来将两者合并在一起,我知道它不是红色,而是一种粉红色,灰色而不是白色,因为我只是将它们与 alpha 混合在一起。

// Start an image context
UIGraphicsBeginImageContext(grabcutResult.size)

// Create rect for this draw session
let rect = CGRect(x: 0.0, y: 0.0, width: grabcutResult.size.width, height: grabcutResult.size.height)
grabcutResult.draw(in: rect)
redGrabcutOutline.draw(in: rect, blendMode: .normal, alpha: 0.5)

let finalImage = UIGraphicsGetImageFromCurrentImageContext()

想法是它应该看起来像这样。

enter image description here

我希望能够快速完成此操作,但我找到的唯一解决方案是 ImageView(它只影响内容的呈现方式而不影响底层 UIImage),或者它们涉及逐个像素地遍历整个图像。

我正在尝试找到一种解决方案,它将轮廓中的所有白色像素都屏蔽为红色,而不必逐个像素地遍历整个图像,因为它太慢了。

理想情况下,如果我能让 openCV 只返回红色轮廓而不是白色轮廓,那会很好,但我认为不可能改变它(也许我错了)。

顺便说一句,使用 swift ......但感谢任何帮助,在此先感谢。

最佳答案

这可能对您有用——仅使用 Swift 代码...

extension UIImage {

func maskWithColor(color: UIColor) -> UIImage? {

let maskingColors: [CGFloat] = [1, 255, 1, 255, 1, 255]
let bounds = CGRect(origin: .zero, size: size)

let maskImage = cgImage!
var returnImage: UIImage?

// make sure image has no alpha channel
let rFormat = UIGraphicsImageRendererFormat()
rFormat.opaque = true
let renderer = UIGraphicsImageRenderer(size: size, format: rFormat)
let noAlphaImage = renderer.image {
(context) in
self.draw(at: .zero)
}

let noAlphaCGRef = noAlphaImage.cgImage

if let imgRefCopy = noAlphaCGRef?.copy(maskingColorComponents: maskingColors) {

let rFormat = UIGraphicsImageRendererFormat()
rFormat.opaque = false
let renderer = UIGraphicsImageRenderer(size: size, format: rFormat)
returnImage = renderer.image {
(context) in
context.cgContext.clip(to: bounds, mask: maskImage)
context.cgContext.setFillColor(color.cgColor)
context.cgContext.fill(bounds)
context.cgContext.draw(imgRefCopy, in: bounds)
}

}
return returnImage
}

}

此扩展返回一个 UIImage,其中白色替换为传递的 UIColor,黑色“背景”变为透明。

以这种方式使用它:

// change filled white star to gray with transparent background
let modFilledImage = filledImage.maskWithColor(color: UIColor(red: 200, green: 200, blue: 200))

// change outlined white star to red with transparent background
let modOutlineImage = outlineImage.maskWithColor(color: UIColor.red)

// combine the images on a black background

这是一个完整的示例,使用您的两个原始图像(大部分代码设置 ImageView 以显示结果):

extension UIImage {

func maskWithColor(color: UIColor) -> UIImage? {

let maskingColors: [CGFloat] = [1, 255, 1, 255, 1, 255]
let bounds = CGRect(origin: .zero, size: size)

let maskImage = cgImage!
var returnImage: UIImage?

// make sure image has no alpha channel
let rFormat = UIGraphicsImageRendererFormat()
rFormat.opaque = true
let renderer = UIGraphicsImageRenderer(size: size, format: rFormat)
let noAlphaImage = renderer.image {
(context) in
self.draw(at: .zero)
}

let noAlphaCGRef = noAlphaImage.cgImage

if let imgRefCopy = noAlphaCGRef?.copy(maskingColorComponents: maskingColors) {

let rFormat = UIGraphicsImageRendererFormat()
rFormat.opaque = false
let renderer = UIGraphicsImageRenderer(size: size, format: rFormat)
returnImage = renderer.image {
(context) in
context.cgContext.clip(to: bounds, mask: maskImage)
context.cgContext.setFillColor(color.cgColor)
context.cgContext.fill(bounds)
context.cgContext.draw(imgRefCopy, in: bounds)
}

}
return returnImage
}

}

class MaskWorkViewController: UIViewController {

let origFilledImgView: UIImageView = {
let v = UIImageView()
v.translatesAutoresizingMaskIntoConstraints = false
v.contentMode = .center
return v
}()

let origOutlineImgView: UIImageView = {
let v = UIImageView()
v.translatesAutoresizingMaskIntoConstraints = false
v.contentMode = .center
return v
}()

let modifiedFilledImgView: UIImageView = {
let v = UIImageView()
v.translatesAutoresizingMaskIntoConstraints = false
v.contentMode = .center
return v
}()

let modifiedOutlineImgView: UIImageView = {
let v = UIImageView()
v.translatesAutoresizingMaskIntoConstraints = false
v.contentMode = .center
return v
}()

let combinedImgView: UIImageView = {
let v = UIImageView()
v.translatesAutoresizingMaskIntoConstraints = false
v.contentMode = .center
return v
}()

let origStack: UIStackView = {
let v = UIStackView()
v.translatesAutoresizingMaskIntoConstraints = false
v.axis = .horizontal
v.spacing = 20
return v
}()

let modifiedStack: UIStackView = {
let v = UIStackView()
v.translatesAutoresizingMaskIntoConstraints = false
v.axis = .horizontal
v.spacing = 20
return v
}()

let mainStack: UIStackView = {
let v = UIStackView()
v.translatesAutoresizingMaskIntoConstraints = false
v.axis = .vertical
v.alignment = .center
v.spacing = 10
return v
}()

override func viewDidLoad() {
super.viewDidLoad()

guard let filledImage = UIImage(named: "StarFill"),
let outlineImage = UIImage(named: "StarEdge") else {
return
}

var modifiedFilledImage: UIImage = UIImage()
var modifiedOutlineImage: UIImage = UIImage()
var combinedImage: UIImage = UIImage()

// for both original images, replace white with color
// and make black transparent
if let modFilledImage = filledImage.maskWithColor(color: UIColor(red: 200, green: 200, blue: 200)),
let modOutlineImage = outlineImage.maskWithColor(color: UIColor.red) {

modifiedFilledImage = modFilledImage
modifiedOutlineImage = modOutlineImage

let rFormat = UIGraphicsImageRendererFormat()
rFormat.opaque = true

let renderer = UIGraphicsImageRenderer(size: modifiedFilledImage.size, format: rFormat)

// combine modified images on black background
combinedImage = renderer.image {
(context) in
context.cgContext.setFillColor(UIColor.black.cgColor)
context.cgContext.fill(CGRect(origin: .zero, size: modifiedFilledImage.size))
modifiedFilledImage.draw(at: .zero)
modifiedOutlineImage.draw(at: .zero)
}

}

// setup image views and set .image properties
setupUI(filledImage.size)

origFilledImgView.image = filledImage
origOutlineImgView.image = outlineImage

modifiedFilledImgView.image = modifiedFilledImage
modifiedOutlineImgView.image = modifiedOutlineImage

combinedImgView.image = combinedImage

}

func setupUI(_ imageSize: CGSize) -> Void {

origStack.addArrangedSubview(origFilledImgView)
origStack.addArrangedSubview(origOutlineImgView)

modifiedStack.addArrangedSubview(modifiedFilledImgView)
modifiedStack.addArrangedSubview(modifiedOutlineImgView)

var lbl = UILabel()
lbl.textAlignment = .center
lbl.text = "Original Images"

mainStack.addArrangedSubview(lbl)

mainStack.addArrangedSubview(origStack)

lbl = UILabel()
lbl.textAlignment = .center
lbl.numberOfLines = 0
lbl.text = "Modified Images\n(UIImageViews have Green Background)"

mainStack.addArrangedSubview(lbl)

mainStack.addArrangedSubview(modifiedStack)

lbl = UILabel()
lbl.textAlignment = .center
lbl.text = "Combined on Black Background"

mainStack.addArrangedSubview(lbl)

mainStack.addArrangedSubview(combinedImgView)

view.addSubview(mainStack)

NSLayoutConstraint.activate([

mainStack.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20.0),
mainStack.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0.0),

])

[origFilledImgView, origOutlineImgView, modifiedFilledImgView, modifiedOutlineImgView, combinedImgView].forEach {

$0.backgroundColor = .green

NSLayoutConstraint.activate([

$0.widthAnchor.constraint(equalToConstant: imageSize.width),
$0.heightAnchor.constraint(equalToConstant: imageSize.height),

])

}

}

}

结果,显示原始、修改和最终组合图像... ImageView 具有绿色背景以显示透明区域:

enter image description here

关于ios - 更改 UIImage 中的白色像素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58307979/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com