Skip to content

Commit

Permalink
Merge branch 'feature/white_to_transparent'
Browse files Browse the repository at this point in the history
  • Loading branch information
Wilhelm Oks committed Feb 23, 2020
2 parents 6a39f0e + 07aee10 commit 7016847
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 1 deletion.
8 changes: 7 additions & 1 deletion Sources/AppetizerCL/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ func main() {
let androidIconPathArgument = parser.add(option: "--androidIcon", shortName: "-a", kind: PathArgument.self, usage: "The path to a directory where to generate the Android icon with different sizes.")
let androidFolderPrefixArgument = parser.add(option: "--androidFolderPrefix", shortName: "-afp", kind: String.self, usage: "The folder prefix for the Android images. Example: 'mipmap' will generate folders like 'mipmap-mdpi' and 'mipmap-xhdpi'. Default is 'drawable'.")
let singleIconPathArgument = parser.add(option: "--singleIcon", shortName: "-si", kind: PathArgument.self, usage: "The path to a directory where to generate a single icon with the specified size.")
let clearWhiteArgument = parser.add(option: "--clearWhite", shortName: "-cw", kind: Bool.self, usage: "Make white color areas transparent. Useful to remove white background.")

do {
let parsedArguments = try parser.parse(Array(ProcessInfo.processInfo.arguments.dropFirst()))
Expand All @@ -39,10 +40,15 @@ func main() {
let androidIconPath = parsedArguments.get(androidIconPathArgument)
let androidFolderPrefix = parsedArguments.get(androidFolderPrefixArgument) ?? "drawable"
let singleIconPath = parsedArguments.get(singleIconPathArgument)
let clearWhite = parsedArguments.get(clearWhiteArgument) ?? false

let inputFilePathString = inputFilePath.path.pathString

let bigImage = try NSImage.from(filePath: inputFilePathString, sizeX: sizeX, sizeY: sizeY)
var bigImage = try NSImage.from(filePath: inputFilePathString, sizeX: sizeX, sizeY: sizeY)

if clearWhite {
bigImage = bigImage.clearedWhite()
}

let tintedImage = bigImage.tinted(withColor: tintColor)

Expand Down
48 changes: 48 additions & 0 deletions Sources/AppetizerCore/NSImageExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,28 @@ public extension NSImage {
return copy
}

private func cgImageFromCiImage(_ inputImage: CIImage, rect: CGRect) -> CGImage {
let context = CIContext(options: nil)
if let cgImage = context.createCGImage(inputImage, from: rect) {
return cgImage
}
fatalError("could not convert CIImage to CGImage")
}

func clearedWhite() -> NSImage {
let sourceNsImage = self
let cgImage = sourceNsImage.cgImage(forProposedRect: nil, context: nil, hints: [:])!
let ciImage = CIImage(cgImage: cgImage)
let filter = ClearWhiteFilter()
filter.assignInputImage(ciImage)
let outputImage = filter.outputImage!

let imageSize = CGSize(width: cgImage.width, height: cgImage.height)
let outputCgImage = cgImageFromCiImage(outputImage, rect: .init(origin: .zero, size: imageSize))

return NSImage(cgImage: outputCgImage, size: sourceNsImage.size)
}

func saveAsPng(fileUrl url: URL) throws {
guard let imageData = self.tiffRepresentation else {
throw ImageFileWriteError.dataRepresentationError
Expand All @@ -64,3 +86,29 @@ public extension NSImage {
try pngImage.write(to: url)
}
}

@objcMembers fileprivate class ClearWhiteFilter : CIFilter {
var inputImage: CIImage?

private static let kernels = CIKernel.makeKernels(source:
"""
kernel vec4 clearWhite(sampler image) {
vec4 t = sample(image, samplerCoord(image));
float brightness = (t.r + t.g + t.b) / 3.0;
float i = 1.0 - brightness;
t.a = min(i, t.a);
return t;
}
"""
)!

override public var outputImage: CIImage? {
let src = CISampler(image: self.inputImage!)
let kernel = ClearWhiteFilter.kernels[0]
return self.apply(kernel, arguments: [src], options: nil)
}

func assignInputImage(_ image: CIImage) {
self.setValue(image, forKey: kCIInputImageKey)
}
}

0 comments on commit 7016847

Please sign in to comment.