admin管理员组文章数量:1220535
I am trying to create an NSImage in macOS using NSBitmapImageRep while having full control over its pixel data. Specifically, I want to:
Manually allocate and fill pixel data with a solid color.
Support both RGB (when hasAlpha = false) and RGBA (when hasAlpha = true).
Ensure no automatic padding is added when hasAlpha = false (i.e., the image should be stored in memory as tightly packed RGB data without extra unused bytes).
Avoid using NSGraphicsContext or CGContext, relying solely on NSBitmapImageRep to construct the image, because, based on what I learned from other questions and issues, NSGraphicsContext does not support RGB-only images.
Here is my function, but I still see unwanted padding added to my image. Here is the output of this code:
Expected Bytes Per Row: 3072 bytes/row
Actual Bytes Per Row: 4096 bytes/row
Image has padding! Extra 1024 bytes per row.
use case:
let size: NSSize = NSSize(width: 1024, height: 1024)
let myImage = createImage(hasAlpha: false, pixelSize: size, color: .red)
if let validImage: NSImage = myImage {
if let tiffData: Data = validImage.tiffRepresentation, let nsBitmapImageRep: NSBitmapImageRep = NSBitmapImageRep(data: tiffData) {
let expectedBytesPerRow = nsBitmapImageRep.samplesPerPixel*nsBitmapImageRep.pixelsWide
let actualBytesPerRow = nsBitmapImageRep.bytesPerRow
print("Expected Bytes Per Row: \(expectedBytesPerRow) bytes/row")
print("Actual Bytes Per Row: \(actualBytesPerRow) bytes/row")
if actualBytesPerRow > expectedBytesPerRow {
print("Image has padding! Extra \(actualBytesPerRow - expectedBytesPerRow) bytes per row.")
} else {
print("No padding detected.")
}
}
}
func createImage(hasAlpha: Bool, pixelSize: NSSize, color: NSColor) -> NSImage? {
let width = Int(pixelSize.width)
let height = Int(pixelSize.height)
let components = hasAlpha ? 4 : 3 // RGBA or RGB
let bitsPerSample = 8
let bytesPerPixel = components
let bytesPerRow = width * bytesPerPixel // Ensure exact memory layout, no padding
// Allocate memory for pixel buffer
guard let pixelData = malloc(height * bytesPerRow)?.assumingMemoryBound(to: UInt8.self) else {
print("Failed to allocate memory.")
return nil
}
defer { free(pixelData) } // Free memory on function exit
// Convert color to RGB space
let colorSpace = NSColorSpace.deviceRGB
guard let colorInRGB = color.usingColorSpace(colorSpace) else {
print("Failed to convert color to RGB space.")
return nil
}
let red = UInt8(colorInRGB.redComponent * 255)
let green = UInt8(colorInRGB.greenComponent * 255)
let blue = UInt8(colorInRGB.blueComponent * 255)
let alpha = hasAlpha ? UInt8(colorInRGB.alphaComponent * 255) : 255
// Fill pixel buffer manually
for y in 0..<height {
for x in 0..<width {
let pixelIndex = (y * bytesPerRow) + (x * bytesPerPixel)
pixelData[pixelIndex] = red
pixelData[pixelIndex + 1] = green
pixelData[pixelIndex + 2] = blue
if hasAlpha {
pixelData[pixelIndex + 3] = alpha
}
}
}
// Create a pointer to the pixel buffer
var pixelDataPlane: UnsafeMutablePointer<UInt8>? = pixelData
// Create NSBitmapImageRep without extra padding
guard let bitmapRep = NSBitmapImageRep(
bitmapDataPlanes: &pixelDataPlane, // Pass pointer to pointer
pixelsWide: width,
pixelsHigh: height,
bitsPerSample: bitsPerSample,
samplesPerPixel: components,
hasAlpha: hasAlpha,
isPlanar: false,
colorSpaceName: .deviceRGB,
bytesPerRow: bytesPerRow, // Prevent unwanted padding
bitsPerPixel: bitsPerSample * bytesPerPixel
) else {
print("Failed to create bitmap representation.")
return nil
}
// Create final NSImage
let image = NSImage(size: pixelSize)
image.addRepresentation(bitmapRep)
return image
}
版权声明:本文标题:swift - Unwanted Padding in Image Created with NSBitmapImageRep Despite Manual Pixel Allocation - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1739256462a2155156.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论