first commit
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
import AppKit
|
||||
import CoreGraphics
|
||||
import Foundation
|
||||
|
||||
// Die Zeichnungen sind weiss gefüllt mit dunklen Linien und Fenstern. Als
|
||||
// Schablone eingefärbt geht beides verloren, weil alles Deckende zur
|
||||
// Tintfarbe wird - übrig bleibt eine massive Fläche.
|
||||
//
|
||||
// Deshalb wird die Helligkeit in Deckkraft übersetzt: dunkle Linien werden
|
||||
// voll deckend, die helle Karosserie nur angedeutet. Eingefärbt ergibt das
|
||||
// eine gefüllte Form, in der die Details erhalten bleiben.
|
||||
|
||||
let arguments = CommandLine.arguments
|
||||
guard arguments.count >= 3,
|
||||
let source = NSImage(contentsOfFile: arguments[1]),
|
||||
let image = source.cgImage(forProposedRect: nil, context: nil, hints: nil) else {
|
||||
print("Quelle nicht lesbar"); exit(1)
|
||||
}
|
||||
|
||||
let width = image.width, height = image.height
|
||||
let bytesPerRow = width * 4
|
||||
var pixels = [UInt8](repeating: 0, count: bytesPerRow * height)
|
||||
guard let context = CGContext(data: &pixels, width: width, height: height,
|
||||
bitsPerComponent: 8, bytesPerRow: bytesPerRow,
|
||||
space: CGColorSpaceCreateDeviceRGB(),
|
||||
bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) else {
|
||||
print("Puffer nicht anlegbar"); exit(1)
|
||||
}
|
||||
context.draw(image, in: CGRect(x: 0, y: 0, width: width, height: height))
|
||||
|
||||
/// Wie stark die Fläche noch durchscheint.
|
||||
let fill = 0.22
|
||||
var changed = 0
|
||||
|
||||
for index in stride(from: 0, to: pixels.count, by: 4) {
|
||||
let alpha = Double(pixels[index + 3]) / 255
|
||||
guard alpha > 0.02 else {
|
||||
pixels[index] = 0; pixels[index + 1] = 0; pixels[index + 2] = 0; pixels[index + 3] = 0
|
||||
continue
|
||||
}
|
||||
// Premultipliziert: erst zurückrechnen, um die echte Helligkeit zu sehen.
|
||||
let r = Double(pixels[index]) / 255 / alpha
|
||||
let g = Double(pixels[index + 1]) / 255 / alpha
|
||||
let b = Double(pixels[index + 2]) / 255 / alpha
|
||||
let brightness = min(1, max(0, 0.299 * r + 0.587 * g + 0.114 * b))
|
||||
|
||||
let newAlpha = alpha * (fill + (1 - fill) * (1 - brightness))
|
||||
// Die Farbe selbst spielt keine Rolle, sie wird ohnehin eingefärbt.
|
||||
let value = UInt8(newAlpha * 255)
|
||||
pixels[index] = value; pixels[index + 1] = value; pixels[index + 2] = value
|
||||
pixels[index + 3] = value
|
||||
changed += 1
|
||||
}
|
||||
|
||||
guard let result = context.makeImage() else { print("Bild leer"); exit(1) }
|
||||
let rep = NSBitmapImageRep(cgImage: result)
|
||||
guard let png = rep.representation(using: .png, properties: [:]) else {
|
||||
print("PNG nicht erzeugbar"); exit(1)
|
||||
}
|
||||
try png.write(to: URL(fileURLWithPath: arguments[2]))
|
||||
print("\(arguments[2]): \(changed) Bildpunkte umgesetzt")
|
||||
Reference in New Issue
Block a user