从像素数据重建图像
Recreating image from pixel data
我有以下代码:
GameScene.swift
import SpriteKit
import GameKit
class GameScene : SKScene {
var circleHolder:CircleHolder = CircleHolder()
override func didMove(to view: SKView) {
self.addChild(circleHolder)
}
}
CircleHolder.swift
import Foundation
import SpriteKit
class CircleHolder : SKNode {
var circles:[Circle] = [Circle]()
override init() {
super.init()
var image:UIImage = UIImage(named: "Circles")!
let width = Int(image.size.width)
let height = Int(image.size.height)
if let cfData = image.cgImage?.dataProvider?.data, let pointer = CFDataGetBytePtr(cfData) {
for x in 0..<width {
for y in 0..<height {
let pixelAddress = ((Int(image.size.width) * y) + x ) * 4
let r = CGFloat(pointer.advanced(by: pixelAddress).pointee) / CGFloat(255.0)
let g = CGFloat(pointer.advanced(by: pixelAddress + 1).pointee) / CGFloat(255.0)
let b = CGFloat(pointer.advanced(by: pixelAddress + 2).pointee) / CGFloat(255.0)
let a = CGFloat(pointer.advanced(by: pixelAddress + 3).pointee) / CGFloat(255.0)
let color = UIColor(red: r, green: g, blue: b, alpha: a)
var c = Circle(x: CGFloat(x), y: CGFloat(y), color: color)
circles.append(c)
self.addChild(c)
}
}
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Circle.swift
import Foundation
import SpriteKit
class Circle : SKNode {
var circle:SKShapeNode?
init(x:CGFloat, y:CGFloat, color:UIColor) {
super.init()
circle = SKShapeNode(circleOfRadius: 1)
circle?.fillColor = color
circle?.position.x = x
circle?.position.y = y
circle?.lineWidth = 0
self.addChild(circle!)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
我正在尝试在我的场景中将实心圆圈放置到 'recreate' UIImage 中的图像。这是我要重新创建的图像:
但我最终得到了这个:
谁能指出我逻辑上的错误?
您的图片似乎没有您期望的属性。它可能有一个 alpha 通道或其他改变字节尺寸的东西。
不是假设每个像素 4 个字节,而是查询图像的实际属性:
let bytesPerRow = image.cgImage!.bytesPerRow
let bitsPerPixel = image.cgImage!.bitsPerPixel
let bitsPerComponent = image.cgImage!.bitsPerComponent
let bytesPerPixel = bitsPerPixel / bitsPerComponent
然后使用这些属性计算像素地址:
let pixelAddress = y * bytesPerRow + x * bytesPerPixel
我有以下代码:
GameScene.swift
import SpriteKit
import GameKit
class GameScene : SKScene {
var circleHolder:CircleHolder = CircleHolder()
override func didMove(to view: SKView) {
self.addChild(circleHolder)
}
}
CircleHolder.swift
import Foundation
import SpriteKit
class CircleHolder : SKNode {
var circles:[Circle] = [Circle]()
override init() {
super.init()
var image:UIImage = UIImage(named: "Circles")!
let width = Int(image.size.width)
let height = Int(image.size.height)
if let cfData = image.cgImage?.dataProvider?.data, let pointer = CFDataGetBytePtr(cfData) {
for x in 0..<width {
for y in 0..<height {
let pixelAddress = ((Int(image.size.width) * y) + x ) * 4
let r = CGFloat(pointer.advanced(by: pixelAddress).pointee) / CGFloat(255.0)
let g = CGFloat(pointer.advanced(by: pixelAddress + 1).pointee) / CGFloat(255.0)
let b = CGFloat(pointer.advanced(by: pixelAddress + 2).pointee) / CGFloat(255.0)
let a = CGFloat(pointer.advanced(by: pixelAddress + 3).pointee) / CGFloat(255.0)
let color = UIColor(red: r, green: g, blue: b, alpha: a)
var c = Circle(x: CGFloat(x), y: CGFloat(y), color: color)
circles.append(c)
self.addChild(c)
}
}
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Circle.swift
import Foundation
import SpriteKit
class Circle : SKNode {
var circle:SKShapeNode?
init(x:CGFloat, y:CGFloat, color:UIColor) {
super.init()
circle = SKShapeNode(circleOfRadius: 1)
circle?.fillColor = color
circle?.position.x = x
circle?.position.y = y
circle?.lineWidth = 0
self.addChild(circle!)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
我正在尝试在我的场景中将实心圆圈放置到 'recreate' UIImage 中的图像。这是我要重新创建的图像:
但我最终得到了这个:
谁能指出我逻辑上的错误?
您的图片似乎没有您期望的属性。它可能有一个 alpha 通道或其他改变字节尺寸的东西。
不是假设每个像素 4 个字节,而是查询图像的实际属性:
let bytesPerRow = image.cgImage!.bytesPerRow
let bitsPerPixel = image.cgImage!.bitsPerPixel
let bitsPerComponent = image.cgImage!.bitsPerComponent
let bytesPerPixel = bitsPerPixel / bitsPerComponent
然后使用这些属性计算像素地址:
let pixelAddress = y * bytesPerRow + x * bytesPerPixel