Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];

Вниз

Как загрузить BMP в массив?   Найти похожие ветки 

 
kalexi   (2008-09-11 14:37) [0]

Нужно загрузить bmp файл и перевести его в массив типа array [0..width*height*3] of byte;. Как это реализовать без сторонних библиотек (только на Windows.pas)?


 
Renegat ©   (2008-09-11 14:43) [1]

GetDIBits/CreateDIBSection + F1.
Пример, к сожалению, есть только под asm.


 
MBo ©   (2008-09-11 14:46) [2]

>Нужно загрузить bmp файл и перевести его в массив
Для чего?
ScanLine, например, позволяет работать напрямую с цветовыми данными


 
Vlad Oshin ©   (2008-09-11 17:13) [3]

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]


 
kalexi   (2008-09-11 18:03) [4]

2 Renegat
Рассеяно, но попытаюсь поискать. Дай асм исходники плз.

2 MBo, Vlad Oshin
Блин, да что же такое... Неужели нельзя полностью посмотреть вопрос? А? И в ветке WinApi положено же! Мне не нужны ExtCtrls, Graphics и другие библиотеки, надо сделать это средствами винды. С VCL любой дурак сделает...


 
Sapersky   (2008-09-11 19:07) [5]

LoadImage + GetDIBits или непосредственная загрузка в массив, благо формат простой, заголовок [+ палитра] + данные.

А откуда, кстати, такая ненависть к библиотекам?
Если из-за размера exe - так есть FastLIB, KOL.TBitmap, SpriteUtils, которые дают весьма компактный размер. Даже если хочешь писать свою, полезно для начала посмотреть как сделано у других.


 
Renegat ©   (2008-09-11 21:08) [6]

 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 <{07BF80980h, 0BF32h, 0101Ah, {08Bh, 0BBh, 000h, 0AAh, 000h, 030h, 00Ch, 0ABh}}>;
   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.
Если разберётесь - ваше счастье ;)


 
Renegat ©   (2008-09-11 21:16) [7]

Впрочем, я зря это выкладывал. Если делфяной 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].


 
kalexi   (2008-09-11 21:42) [8]

2 Sapersky
Спасибо, на счет библиотек - посмотрю.

2 Renegat
Спс, буду изучать ))


 
Renegat ©   (2008-09-11 21:44) [9]

Ах да. Описание входных парамов для функции LoadGIFJPGMem:

G  - блок памяти с картинкой внутре (указатель, разумеется, а не сам блок).
Sz - ^^^ его размер
BD - если равен 0, картинка загружается в DDB, иначе - в DIB, и по адресу, который здесь передан, пишется DC созданного битмапа.
Sk - смещение относительно первого байта в блоке RAM содержащем картинку.


 
kalexi   (2008-09-11 21:57) [10]

Все! Решил! Формат действительно очень простой, поэтому не стану морочить голову и сделаю без WinApi


 
Renegat ©   (2008-09-11 21:59) [11]

...а если битмап попадётся не 32-битный, а скажем 2-цветный?


 
MBo ©   (2008-09-12 05:09) [12]

>Если делфяной TBitmap изначально является DIB-ом
Загружаемый из файла - да, является DIB-ом.
При создании TBitmap.Create  -  DDB, но если затем задать PixelFormat или HandleType - то DIB


 
GrayFace ©   (2008-09-13 21:38) [13]

в WinAPI:
GetBitmapBits() и SetBitmapBits()


 
Renegat ©   (2008-09-13 21:50) [14]

> [13] GrayFace ©   (13.09.08 21:38)

К сожалению, это не совсем так.

> The GetBitmapBits function is not implemented in the Win32 API.


 
GrayFace ©   (2008-09-14 01:40) [15]

В Висте? На ХР отлично работает.


 
Григорьев Антон ©   (2008-09-15 12:14) [16]


> 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.


 
brother ©   (2008-09-15 12:14) [17]

> У меня про GetBitmapBits другое написано:

где?


 
Григорьев Антон ©   (2008-09-15 12:31) [18]


> brother ©   (15.09.08 12:14) [17]
> где?

В той версии MSDN, которая у меня установлена. Да и вот здесь то же самое: http://msdn.microsoft.com/en-us/library/ms532332(VS.85).aspx


 
brother ©   (2008-09-15 12:56) [19]

> [18] Григорьев Антон ©   (15.09.08 12:31)


> is not implemented in the Win32


> only for compatibility with 16-

;)


 
имя   (2008-11-19 00:41) [20]

Удалено модератором


 
han_malign ©   (2008-11-19 10:04) [21]


> но если затем задать PixelFormat или HandleType - то DIB

- или Dormant :)

> Загружаемый из файла - да, является DIB-ом.

- почти - если его целиком загрузить образ файла в память, получив таким образом "packed bitmap"(MSDN: Windows GDI - BITMAPINFO - remarks) - и скормить его StretchDIBits то для 8,16 - бит - прокатывает, а для 32 - нет(есть подозрение, что нужно выравнивание на страницу памяти - не проверял)


 
имя   (2009-04-02 09:14) [22]

Удалено модератором



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.5 MB
Время: 0.069 c
4-1232881341
Soulghai
2009-01-25 14:02
2010.08.27
Встроить код в готовую программу


15-1273573286
Дмитрий Белькевич
2010-05-11 14:21
2010.08.27
Возможно ли доступиться из JavaScript к OLE интерфейсам?


15-1266662604
oldman
2010-02-20 13:43
2010.08.27
Майкрософт прикалывается?


15-1270794656
Den
2010-04-09 10:30
2010.08.27
Тип дистрибутива


4-1226752749
VolMyr
2008-11-15 15:39
2010.08.27
хук на интернет адрес





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский