This question already has an answer here:
Masking an image in Swift using CALayer and UIImage
(1 answer)
Closed 6 years ago.
I want UIImage masking something like this as shown in the image below but using coregraphics masking, any answer is appreciated
func maskImage(image:UIImage, mask:(UIImage))-> UIImage {
let imageReference = image.cgImage
let maskReference = mask.cgImage
let imageMask = CGImage(maskWidth: maskReference!.width, height: maskReference!.height, bitsPerComponent: maskReference!.bitsPerComponent, bitsPerPixel: maskReference!.bitsPerPixel, bytesPerRow: maskReference!.bytesPerRow, provider: maskReference!.dataProvider!, decode: nil, shouldInterpolate: true)
let maskedReference = imageReference!.masking(imageMask!)
let maskedImage = UIImage(cgImage:maskedReference!)
return maskedImage
}
Related
I want add lights effect on image. I have masked on that and this is my image
For that I have code to use masking image
func maskImage(image:UIImage, mask:(UIImage))->UIImage{
let imageReference = image.cgImage
let maskReference = mask.cgImage
let imageMask = CGImage(maskWidth: maskReference!.width,
height: maskReference!.height,
bitsPerComponent: maskReference!.bitsPerComponent,
bitsPerPixel: maskReference!.bitsPerPixel,
bytesPerRow: maskReference!.bytesPerRow,
provider: maskReference!.dataProvider!, decode: nil, shouldInterpolate: true)
let maskedReference = imageReference!.masking(imageMask!)
let maskedImage = UIImage(cgImage:maskedReference!)
return maskedImage
}
And result is get to this
it will get only in white
Please help me
I'm assuming you want to remove the black background and just show the lens flare. For this you can use screen blend mode.
func filteredImage(image: UIImage, effect: UIImage) -> UIImage? {
guard let imageReference = CIImage(image: image),
let effectReference = CIImage(image: effect) else {
return nil
}
let filteredCIImage = effectReference.applyingFilter(
"CIScreenBlendMode",
parameters: [kCIInputBackgroundImageKey: imageReference]
)
let filteredImage = UIImage(ciImage: filteredCIImage)
return filteredImage
}
Given this image:
Is there a way to get a bezier path of the non-alpha parts from this image? Here, it would be the part delimited by the cat.
I know how to mask an image with another one:
func maskImage(image: UIImage, withMask maskImage: UIImage) -> UIImage {
let maskRef = maskImage.cgImage
let mask = CGImage(
maskWidth: maskRef!.width,
height: maskRef!.height,
bitsPerComponent: maskRef!.bitsPerComponent,
bitsPerPixel: maskRef!.bitsPerPixel,
bytesPerRow: maskRef!.bytesPerRow,
provider: maskRef!.dataProvider!,
decode: nil,
shouldInterpolate: false)
let masked = image.cgImage!.masking(mask!)
let maskedImage = UIImage(cgImage: masked!)
return maskedImage
}
But don't know how to get a bezier path from this.
Thanks for your help!
I am trying to save a drawing generated on iOS using openGL ES to an PNG file using CGDataProvider and CGImage functions. I have found some code on the web in Objective-C which I converted to Swift 3. The code compiles but fails during runtime throwing an error:
fatal error: unexpectedly found nil while unwrapping an Optional value at this line:
let iref: CGImage = CGImage(pngDataProviderSource: provider!, decode: nil, shouldInterpolate: true, intent: CGColorRenderingIntent.defaultIntent)!
Code:
let x: Int = 0
let y: Int = 0
let dataLength: Int = Int(width) * Int(height) * 4
let pixels: UnsafeMutableRawPointer? = malloc(dataLength * MemoryLayout<GLubyte>.size)
glPixelStorei(GL_PACK_ALIGNMENT.ui, 4)
glReadPixels(GLint(x), GLint(y), GLsizei(width), GLsizei(height), GLenum(GL_RGBA), GL_UNSIGNED_BYTE.ui, pixels)
let pixelData: UnsafePointer = (UnsafeRawPointer(pixels)?.assumingMemoryBound(to: UInt8.self))!
let cfdata: CFData = CFDataCreate(kCFAllocatorDefault, pixelData, dataLength * MemoryLayout<GLubyte>.size)
let provider: CGDataProvider! = CGDataProvider(data: cfdata)
let iref: CGImage = CGImage(pngDataProviderSource: provider!, decode: nil, shouldInterpolate: true, intent: CGColorRenderingIntent.defaultIntent)!
UIGraphicsBeginImageContext(CGSize(width: CGFloat(width), height: CGFloat(height)))
let cgcontext: CGContext? = UIGraphicsGetCurrentContext()
cgcontext!.setBlendMode(CGBlendMode.copy)
cgcontext!.draw(iref, in: CGRect(x: CGFloat(0.0), y: CGFloat(0.0), width: CGFloat(width), height: CGFloat(height)))
let image: UIImage? = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
I can't find any help on the web for Swift 3. Could you please help in fixing this error.
As suggested by Matic Oblak, the error was gone and the code worked properly, when I replaced this line in the above code
let iref: CGImage = CGImage(pngDataProviderSource: provider!, decode: nil, shouldInterpolate: true, intent: CGColorRenderingIntent.defaultIntent)!
with this
let iref: CGImage? = CGImage(width: Int(width), height: Int(height), bitsPerComponent: 8, bitsPerPixel: 32, bytesPerRow: Int(width)*4, space: colorspace!, bitmapInfo: CGBitmapInfo.byteOrder32Big, provider: provider, decode: nil, shouldInterpolate: true, intent: CGColorRenderingIntent.defaultIntent)
New working code:
let x: Int = 0
let y: Int = 0
let dataLength: Int = Int(width) * Int(height) * 4
let pixels: UnsafeMutableRawPointer? = malloc(dataLength * MemoryLayout<GLubyte>.size)
glPixelStorei(GL_PACK_ALIGNMENT.ui, 4)
glReadPixels(GLint(x), GLint(y), GLsizei(width), GLsizei(height), GLenum(GL_RGBA), GL_UNSIGNED_BYTE.ui, pixels)
let pixelData: UnsafePointer = (UnsafeRawPointer(pixels)?.assumingMemoryBound(to: UInt8.self))!
let cfdata: CFData = CFDataCreate(kCFAllocatorDefault, pixelData, dataLength * MemoryLayout<GLubyte>.size)
let provider: CGDataProvider! = CGDataProvider(data: cfdata)
let iref: CGImage? = CGImage(width: Int(width), height: Int(height), bitsPerComponent: 8, bitsPerPixel: 32, bytesPerRow: Int(width)*4, space: colorspace!, bitmapInfo: CGBitmapInfo.byteOrder32Big, provider: provider, decode: nil, shouldInterpolate: true, intent: CGColorRenderingIntent.defaultIntent)
UIGraphicsBeginImageContext(CGSize(width: CGFloat(width), height: CGFloat(height)))
let cgcontext: CGContext? = UIGraphicsGetCurrentContext()
cgcontext!.setBlendMode(CGBlendMode.copy)
cgcontext!.draw(iref, in: CGRect(x: CGFloat(0.0), y: CGFloat(0.0), width: CGFloat(width), height: CGFloat(height)))
let image: UIImage? = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
I have a set of user-generated PNG images that I need to embed into print-ready PDFs. One of the constraints set by the printing company is that all images be in the CMYK colorspace. How do I convert a PNG (or UIImage containing that PNG) to CMYK? By default the colorspace is sRGB.
You should consider CGColorSpace class and CGColorSpaceCreateDeviceCMYK function.
You can create a CGContex using this initializer and pass CMYK color space as a parameter to it. Then just draw a CGImage from that context and create UIImage from it.
Example:
func createCMYK(fromRGB image: UIImage) -> UIImage? {
let size = image.size
let colorSpace:CGColorSpace = CGColorSpaceCreateDeviceCMYK()
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)
guard let context = CGContext(data: nil,
width: Int(size.width),
height: Int(size.height),
bitsPerComponent: 8,
bytesPerRow: 4 * Int(size.width),
space: colorSpace,
bitmapInfo: bitmapInfo.rawValue) else { return nil }
context.draw(image.cgImage!, in: CGRect(origin: .zero, size: size))
guard let cgImage = context.makeImage() else { return nil }
return UIImage(cgImage: cgImage)
}
According to https://developer.apple.com/library/archive/documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_context/dq_context.html#//apple_ref/doc/uid/TP30001066-CH203 "Supported Pixel Formats" table you must use
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue)
to correctly create a context
I created two applications: one for mac and one for iPhone. iPhone sends the video frames it captured to mac using MultipeerConnectivity framework. I have managed to find code for converting an UIimage to grayscale using this code:
func convertToGrayScale(image: UIImage) -> UIImage {
let imageRect:CGRect = CGRectMake(0, 0, image.size.width, image.size.height)
let colorSpace = CGColorSpaceCreateDeviceGray()
let width = image.size.width
let height = image.size.height
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.None.rawValue)
let context = CGBitmapContextCreate(nil, Int(width), Int(height), 8, 0, colorSpace, bitmapInfo.rawValue)
CGContextDrawImage(context, imageRect, image.CGImage)
let imageRef = CGBitmapContextCreateImage(context)
let newImage = UIImage(CGImage: imageRef!)
return newImage
}
In the code below, it sends the video frame to Mac:
func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, fromConnection connection: AVCaptureConnection!) {
let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
CVPixelBufferLockBaseAddress(imageBuffer!, kCVPixelBufferLock_ReadOnly)
let baseAddress = CVPixelBufferGetBaseAddress(imageBuffer!)
let bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer!)
let width = CVPixelBufferGetWidth(imageBuffer!)
let height = CVPixelBufferGetHeight(imageBuffer!)
CVPixelBufferUnlockBaseAddress(imageBuffer!, 0)
let colorSpace = CGColorSpaceCreateDeviceRGB()
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedLast.rawValue)
let context = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, bitmapInfo.rawValue)
let quarzImage = CGBitmapContextCreateImage(context)
let image = UIImage(CGImage: quarzImage!)
let grayImage = convertToGrayScale(image)
let data: NSData = UIImagePNGRepresentation(grayImage)!
delegate?.recievedOutput(data)
}
The delegate method is just sending the data using session.sendData()
So, here comes to the Mac side. When mac received NSData, I created an NSImage from the data and created a .png image file using this code:
func session(session: MCSession, didReceiveData data: NSData, fromPeer peerID: MCPeerID) {
let image: NSImage = NSImage(data: data)!.imageRotatedByDegreess(270)
let cgRef = image.CGImageForProposedRect(nil, context: nil, hints: nil)
let representation = NSBitmapImageRep(CGImage: cgRef!)
let pngData = representation.representationUsingType(NSBitmapImageFileType.NSPNGFileType, properties: [NSImageCompressionFactor: 1.0])
pngData?.writeToFile("/Users/JunhongXu/Desktop/image/\(result.description).png", atomically: true)
result[4]++
self.delegate?.presentRecievedImage(image)
}
Although the image is like the picture below, when I checked my image file property, it is in RGB format. How can I change the ColorSpace of my NSImage to grayscale instead of RGB?
enter image description here
I have found a simple solution to my problem. Since it is already in grayscale when it transimitted to my Mac, I am able to use the code below to convert the image representation's ColorSpace to grayscale and save it as a .png file:
let newRep = representation.bitmapImageRepByConvertingToColorSpace(NSColorSpace.genericGrayColorSpace(), renderingIntent: NSColorRenderingIntent.Default)
let pngData = newRep!.representationUsingType(NSBitmapImageFileType.NSPNGFileType, properties: [NSImageCompressionFactor: 1.0])
pngData?.writeToFile("/Users/JunhongXu/Desktop/image/\(result.description).png", atomically: true)