Closed IAmVigneswaran closed 2 months ago
I'll add a border later in my GrabShot code. You can pick up the code from there. I'll write about it here.
I'll add a border later in my GrabShot code. You can pick up the code from there. I'll write about it here.
Thank you!
I added the ability to create flower rims. The code can be viewed here https://github.com/DenDmitriev/GrabShot/blob/e201097495d839a9096e17da8c2a0797086ea445/GrabShot/Service/ImageRenderService/ImageMergeOperation.swift#L93-L190
static func createContextRectangle(colors: [Color], width: Int, height: Int, border: Int? = nil, borderColor: CGColor? = nil) -> CGContext? {
var widthBorder = border ?? .zero
// Check size border
if widthBorder > width / 10, !(0...99 ~= widthBorder), widthBorder > width / 3 {
widthBorder = .zero
}
let countSegments = colors.count
let widthTotalBorder = widthBorder * (countSegments - 1) + 2 * widthBorder
let widthColors = width - widthTotalBorder
let widthSegment = widthColors / countSegments
let remainder = widthColors % colors.count
let borderColor = borderColor ?? CGColor(srgbRed: 1, green: 1, blue: 1, alpha: 1.0) // white
let borderColorAsUInt = Self.cgColorToUInt32(borderColor)
let colorsAsUInt = colors.map { cgColorToUInt32($0.cgColor ?? CGColor(srgbRed: 0, green: 0, blue: 0, alpha: 1))}
// Pixel line 1D
var pixelsOnLine: [UInt32] = []
pixelsOnLine.reserveCapacity(width)
guard
width >= countSegments
else { return nil }
let createBorder = widthBorder > .zero
colorsAsUInt.forEach { colorAsUInt in
if createBorder {
for _ in Array(1...widthBorder) {
pixelsOnLine.append(borderColorAsUInt)
}
}
for _ in Array(1...widthSegment) {
pixelsOnLine.append(colorAsUInt)
}
}
// Add colors if has remainder pixels 1D
if remainder != 0,
let lastColor = colorsAsUInt.last {
Array(1...remainder).forEach { _ in
pixelsOnLine.append(lastColor)
}
}
// Close line 1D with border
if createBorder {
for _ in Array(1...widthBorder) {
pixelsOnLine.append(borderColorAsUInt)
}
}
// Rectangle pixels 2D
var pixels: [UInt32] = []
pixels.reserveCapacity(width * height)
// Add top border
if createBorder {
let borderLine: [UInt32] = Array(repeating: borderColorAsUInt, count: width * Int(widthBorder))
pixels.append(contentsOf: borderLine)
}
// Add colors rectangles with separator
let heightColors = createBorder ? (height - (widthBorder * 2)) : height
for _ in Array(1...heightColors) {
pixels += pixelsOnLine
}
// Add bottom border
if createBorder {
let borderLine: [UInt32] = Array(repeating: borderColorAsUInt, count: width * Int(widthBorder))
pixels.append(contentsOf: borderLine)
}
let mutableBufferPointer = pixels.withUnsafeMutableBufferPointer { pixelsPtr in
return pixelsPtr.baseAddress
}
let bytesPerRow = width * 4
let bitmapInfo = CGImageAlphaInfo.premultipliedLast.rawValue | CGBitmapInfo.byteOrder32Little.rawValue
let context = CGContext(
data: mutableBufferPointer,
width: width,
height: height,
bitsPerComponent: 8,
bytesPerRow: bytesPerRow,
space: CGColorSpaceCreateDeviceRGB(),
bitmapInfo: bitmapInfo
)
return context
}
private static func cgColorToUInt32(_ cgColor: CGColor) -> UInt32 {
let red255 = UInt32(cgColor.red * 255)
let green255 = UInt32(cgColor.green * 255)
let blue255 = UInt32(cgColor.blue * 255)
let alpha255 = UInt32(cgColor.alpha * 255)
let colorAsUInt: UInt32 = (red255 << 24) | (green255 << 16) | (blue255 << 8) | (alpha255 << 0)
return colorAsUInt
}
@IAmVigneswaran I have added an option for the border. How thick should it be? Currently, it is 5 pixels wide and the color is white. It looks like this:
@milanvarady Let's hardcode this white border option. User's don't have to fiddle with this. Yes, 5px looks about right.
@DenDmitriev Thank you for providing the necessary code.
@DenDmitriev You can update us with relevant code to add white border to the image palette strip.
Thank you.