Delphi TBitmap - почему отличаются пиксели и ScanLine?
При использовании 32-битного TBitmap я переключился с Canvas.Pixels на ScanLine.
Затем я установил значение Red, только чтобы найти, что оно отображается синим цветом.
Есть идеи почему?
Вот выдержка из кода:
procedure TForm1.FormPaint(Sender: TObject);
var
varBitmap: TBitmap;
pLock: PIntegerArray;
iColor: integer;
begin
varBitmap := TBitmap.Create;
varBitmap.PixelFormat := pf32bit;
varBitmap.Width := 800;
varBitmap.Height := 600;
// Set Pixels to Red
varBitmap.Canvas.Pixels[0, 0] := $0000FF;
// Shows $FF0000 (blue)
pLock := varBitmap.ScanLine[0];
iColor := pLock[0];
ShowMessageFmt('%x', [iColor]);
// Set ScanLine to Red
pLock[0] := $0000FF;
// Displays a blue pixel
Canvas.Draw(0, 0, varBitmap);
end;
Кажется, что-то TColor не то же самое, что в памяти, но это не имеет смысла.
Любые предложения приветствуются.;)
2 ответа
32-битные пиксельные данные находятся в $AARRGGBB
формат. Вы устанавливаете синий компонент, а не красный. использование $FF0000
вместо $0000FF
, Или лучше использовать RGB()
функция.
Растровый класс VCL, TBitmap
является оберткой вокруг независимой от Windows растровой карты (DIB) Эти растровые объекты могут хранить растровые изображения в широком разнообразии форматов пикселей. Они могут быть монохромными с одним битом на пиксель, до 32 бит на пиксель, формат, который вы используете. Их также можно использовать для хранения растровых изображений на основе палитры, где каждый пиксель содержит индекс в таблицу цветов.
Два метода доступа к пиксельным данным, на которые вы ссылаетесь, это Pixels
собственностью TCanvas
и ScanLine
собственностью TBitmap
,
Pixels
собственностью TCanvas
это обертка вокруг GDI GetPixel
а также SetPixel
функции. Это функции высокого уровня, которые работают на COLORREF
ценности. Документация для COLORREF
говорит:
Байт младшего разряда содержит значение для относительной интенсивности красного цвета; второй байт содержит значение для зеленого; и третий байт содержит значение для синего цвета. Старший байт должен быть нулевым. Максимальное значение для одного байта составляет 0xFF.
Другими словами, COLORREF
значение имеет фиксированный способ кодирования цвета пикселя. GetPixel
а также SetPixel
функции много обрабатывают преобразование между фиксированным COLORREF
форма и исходные необработанные данные растрового пикселя. Обратите внимание также, что COLORREF
не может представлять значение альфа. COLORREF
значение в формате $00BBGGRR.
С другой стороны, ScanLine
собственностью TBitmap
возвращает вам указатель на необработанные данные пикселей базового объекта DIB. Данные, с которыми вы здесь работаете, представляют собой пиксельные данные 32bpp, и для этих данных принято, что они хранятся в формате $AARRGGBB. Документация Windows для данных 32bpp гласит:
Растровое изображение имеет максимум 2^32 цветов. Если элемент biCompression элемента BITMAPINFOHEADER имеет значение BI_RGB, элемент bmiColors элемента BITMAPINFO имеет значение NULL. Каждый DWORD в массиве растровых изображений представляет относительную интенсивность синего, зеленого и красного для пикселя. Значение для синего - это 8 младших разрядов, за которыми следуют 8 бит для зеленого и красного. Старший байт в каждом DWORD не используется.
Так что на самом деле этот текст неверен и устарел. Старший байт в каждом DWORD
фактически альфа-канал, если он используется.