-
Нужно загрузить bmp файл и перевести его в массив типа array [0..width*height*3] of byte; . Как это реализовать без сторонних библиотек (только на Windows.pas)?
-
GetDIBits/CreateDIBSection + F1. Пример, к сожалению, есть только под asm.
-
>Нужно загрузить bmp файл и перевести его в массив Для чего? ScanLine, например, позволяет работать напрямую с цветовыми данными
-
for h := 0 to Bitmap.Height-1 do begin for w := 0 to Bitmap.Width-1 do begin Color := ColorToRGB(Bitmap.Canvas.Pixels[w,h]); r := GetRValue(Color); g := GetGValue(Color); b := GetBValue(Color); array[]ofbyte := r,g,b end; end;
медленно, и вообще, см
> [2]
-
2 Renegat Рассеяно, но попытаюсь поискать. Дай асм исходники плз.
2 MBo, Vlad Oshin Блин, да что же такое... Неужели нельзя полностью посмотреть вопрос? А? И в ветке WinApi положено же! Мне не нужны ExtCtrls, Graphics и другие библиотеки, надо сделать это средствами винды. С VCL любой дурак сделает...
-
LoadImage + GetDIBits или непосредственная загрузка в массив, благо формат простой, заголовок [+ палитра] + данные.
А откуда, кстати, такая ненависть к библиотекам? Если из-за размера exe - так есть FastLIB, KOL.TBitmap, SpriteUtils, которые дают весьма компактный размер. Даже если хочешь писать свою, полезно для начала посмотреть как сделано у других.
-
LoadGIFJPGMem proc G: DWORD, Sz: DWORD, BD: DWORD, Sk: DWORD;
IPicture STRUCT;
QueryInterface DWORD ?;
AddRef DWORD ?;
Release DWORD ?;
get_Handle DWORD ?;
IPicture ENDS;
IStream STRUCT;
QueryInterface DWORD ?;
AddRef DWORD ?;
Release DWORD ?;
Read DWORD ?;
Write DWORD ?;
Seek DWORD ?;
SetSize DWORD ?;
IStream ENDS;
.data
sGUID_JPG TEXTEQU <}>;
GUID_JPG GUID sGUID_JPG;
.data?
s DWORD ?;
p DWORD ?;
bi BITMAPINFO <>;
.code
PUSH EBX;
invoke CreateStreamOnHGlobal, G, TRUE, ADDR s;
MOV EAX, s;
MOV EBX, DWORD PTR [EAX];
CMP Sk, 0;
JE @seek;
PUSH 0;
PUSH 0;
PUSH 0;
PUSH Sk;
PUSH EAX;
CALL [EBX].IStream.Seek;
@seek:
invoke OleLoadPicture, s, Sz, TRUE, ADDR GUID_JPG, ADDR p;
MOV EAX, p;
MOV EBX, DWORD PTR [EAX];
PUSH OFFSET s;
PUSH EAX;
CALL [EBX].IPicture.get_Handle;
PUSH p;
CALL [EBX].IPicture.AddRef;
invoke CreateCompatibleDC, 0;
PUSH EAX;
PUSH SRCCOPY;
PUSH 0;
PUSH 0;
PUSH EAX;
PUSH s;
PUSH s;
PUSH EAX;
MOV s, EAX;
CALL SelectObject;
CALL GetBitmapSize;
MOVZX EDX, AX;
SHR EAX, 16;
PUSH EAX;
PUSH EDX;
PUSH 0;
PUSH 0;
CMP BD, 0;
JNE @mdib;
invoke CreateCompatibleBitmap, s, EDX, EAX;
MOV Sz, EAX;
PUSH EAX;
invoke CreateCompatibleDC, 0;
MOV s, EAX;
PUSH EAX;
CALL SelectObject;
PUSH s;
CALL BitBlt;
invoke DeleteDC, s;
JMP @mddb;
@mdib:
PUSH EAX;
PUSH EDX;
MOV bi.bmiHeader.biSize, SIZEOF BITMAPINFOHEADER;
POP bi.bmiHeader.biWidth;
POP bi.bmiHeader.biHeight;
MOV bi.bmiHeader.biPlanes, 1;
MOV bi.bmiHeader.biBitCount, 32;
MOV bi.bmiHeader.biCompression, BI_RGB;
invoke CreateCompatibleDC, 0;
MOV EDX, BD;
MOV DWORD PTR [EDX], EAX;
PUSH EAX;
PUSH EAX;
PUSH EAX;
LEA EDX, [EBP+8]; <---- Offset for "G" parameter
invoke CreateDIBSection, s, ADDR bi, DIB_RGB_COLORS, EDX, 0, 0;
MOV Sz, EAX;
MOV DWORD PTR [ESP+4], EAX;
CALL SelectObject;
CALL BitBlt;
@mddb:
CALL DeleteDC;
PUSH p;
CALL [EBX].IPicture.Release;
MOV EAX, Sz;
POP EBX;
RET;
LoadGIFJPGMem endp; Да простят меня модеры за выкладывание такой здоровенной портянки прямо на форум =) То что вам, kalexi, нужно, расположено между метками @mdib и @mddb. Если разберётесь - ваше счастье ;)
-
Впрочем, я зря это выкладывал. Если делфяной TBitmap изначально является DIB-ом (я хз, так ли это - пусть ответят Мастера), то его не нужно пересоздавать как DIB и копировать массив пикселей в него. Можно воспользоваться вот этим: DIBgetRGBarr proc BTFS: HBITMAP;
.data?
dgr BITMAP <>;
.code
invoke GetObject, BTFS, SIZEOF BITMAP, ADDR dgr;
MOV EAX, dgr.bmBits;
RET;
DIBgetRGBarr endp; Выдаёт ссылку (делфийский Pointer) на массив пикселей DIB-а. Структура каждого из элементов такова: три нижних байта - это цвет, верхний - зарезервирован. Обычно там хранят альфа-компонент. Впрочем, даже если исходный битмап - не DIB, его легко можно сконвертить в таковой с помощью лёгкой обработки напильником кода из [6].
-
2 Sapersky Спасибо, на счет библиотек - посмотрю.
2 Renegat Спс, буду изучать ))
-
Ах да. Описание входных парамов для функции LoadGIFJPGMem:
G - блок памяти с картинкой внутре (указатель, разумеется, а не сам блок). Sz - ^^^ его размер BD - если равен 0, картинка загружается в DDB, иначе - в DIB, и по адресу, который здесь передан, пишется DC созданного битмапа. Sk - смещение относительно первого байта в блоке RAM содержащем картинку.
-
Все! Решил! Формат действительно очень простой, поэтому не стану морочить голову и сделаю без WinApi
-
...а если битмап попадётся не 32-битный, а скажем 2-цветный?
-
>Если делфяной TBitmap изначально является DIB-ом Загружаемый из файла - да, является DIB-ом. При создании TBitmap.Create - DDB, но если затем задать PixelFormat или HandleType - то DIB
-
в WinAPI: GetBitmapBits() и SetBitmapBits()
-
> [13] GrayFace © (13.09.08 21:38)
К сожалению, это не совсем так.
> The GetBitmapBits function is not implemented in the Win32 API.
-
В Висте? На ХР отлично работает.
-
> Renegat © (13.09.08 21:50) [14] > К сожалению, это не совсем так. > > The GetBitmapBits function is not implemented in the Win32 > API.
У меня про GetBitmapBits другое написано:
> This function is provided only for compatibility with 16- > bit versions of Windows. Applications should use the GetDIBits > function.
-
> У меня про GetBitmapBits другое написано:
где?
-
-
> [18] Григорьев Антон © (15.09.08 12:31)
> is not implemented in the Win32
> only for compatibility with 16-
;)
-
Удалено модератором
-
> но если затем задать PixelFormat или HandleType - то DIB
- или Dormant :)
> Загружаемый из файла - да, является DIB-ом.
- почти - если его целиком загрузить образ файла в память, получив таким образом "packed bitmap"(MSDN: Windows GDI - BITMAPINFO - remarks) - и скормить его StretchDIBits то для 8,16 - бит - прокатывает, а для 32 - нет(есть подозрение, что нужно выравнивание на страницу памяти - не проверял)
-
Удалено модератором
|