SKSpriteNode, созданный из SKTexture(данные: размер:), проблемы с альфа (непрозрачность)
У меня возникла проблема при создании SKSpriteNode из pixelData.
Ниже мой код.
var pixelData: [UInt32] = [UInt32](count: 256, repeatedValue: 0xff0000ff)
pixelData.appendContentsOf([UInt32](count: 256, repeatedValue: 0xff00ff00))
pixelData.appendContentsOf([UInt32](count: 256, repeatedValue: 0xffff0000))
pixelData.appendContentsOf([UInt32](count: 256, repeatedValue: 0x000000ff))
let data = NSData(bytes: pixelData, length: pixelData.count * sizeof(UInt32))
let texture = SKTexture(data: data, size: CGSize(width: 32, height: 32))
let node = SKSpriteNode(texture: texture, size: CGSize(width: 32, height: 32))
node.position.x = self.frame.midX
node.position.y = self.frame.midY
self.addChild(node)
Это пошло так, как я хочу для трех нижних строк (это первые 3 части в массиве pixelData, 0xff0000ff
, 0xff00ff00
, 0xffff0000
: Красный, зеленый и синий).
Однако я ожидал, что верхняя строка будет полностью прозрачной: 0x000000ff
, что должно означать rgba(1, 0, 0, 0). Но это выглядело так:
Я не знаю, почему это произошло. Мое понимание pixelData неверно? Или это ошибка или что-то в SpriteKit?
Большое спасибо за Вашу помощь!
1 ответ
Из документации для удобства метод для преобразования данных пикселей в SKTexture
,
Компоненты цвета уже должны быть умножены на альфа-значение.
Следовательно, значение 0x000000ff
не определено, так как красный компонент не может быть 0xff
если значение альфа равно 0. Кроме того, несколько не интуитивно понятно представлять цвет пикселя шестнадцатеричным значением, особенно когда компоненты расположены в обратном порядке.
Кроме того, вы можете определить структуру данных для представления цвета, а затем предварительно умножить каждый компонент цвета на альфа-значение во время инициализации:
struct Color {
var red:UInt8
var green:UInt8
var blue:UInt8
var alpha:UInt8
// You can omit the parameters that have default values.
init(red:UInt8=0, green:UInt8=0, blue:UInt8=0, alpha:UInt8=UInt8.max) {
let alphaValue:Float = Float(alpha) / 255
self.red = UInt8(round(Float(red) * alphaValue))
self.green = UInt8(round(Float(blue) * alphaValue))
self.blue = UInt8(round(Float(green) * alphaValue))
self.alpha = alpha
}
}
Затем вы можете определить и инициализировать pixelData
массив с теми же значениями, что и ваш код
var pixelData:[Color] = [Color](count: 256, repeatedValue: Color(red: UInt8.max))
pixelData += [Color](count:256, repeatedValue: Color(green: UInt8.max))
pixelData += [Color](count:256, repeatedValue: Color(blue: UInt8.max))
pixelData += [Color](count:256, repeatedValue: Color(red: UInt8.max, alpha: 0))
и создать NSData
объект с
let data = NSData(bytes: pixelData, length: pixelData.count * sizeof(Color))