News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Dimensions of a bitmap

Started by clamicun, June 14, 2017, 01:53:15 AM

Previous topic - Next topic

clamicun

To get the width and height of a bitmap ..

;============================
INVOKE MultiByteToWideChar,CP_ACP,MB_PRECOMPOSED,offset image_path,-1,ADDR UnicodeFileName,MAX_PATH-1
INVOKE GdipCreateBitmapFromFile,ADDR UnicodeFileName,ADDR BmpImage
INVOKE GdipCreateHBITMAPFromBitmap,BmpImage,ADDR hBitmap,0

INVOKE CreateCompatibleDC,0
mov hMemDC,eax

INVOKE SelectObject,hMemDC,hBitmap
INVOKE GetObject,hBitmap,sizeof(BITMAP),ADDR bm
lea edx,bm

mov eax,BITMAP.bmWidth[edx]
mov image_width,eax

mov eax,BITMAP.bmHeight[edx]
mov image_height,eax

INVOKE DeleteDC,hMemDC
;===========================
Is there a "simpler" function to get the dimension ?

If I upload a whole directory of fotos (jpgs) into a database it slows down my proc and on "special ocasions ?" (weekdays, humour of my machine, weather  a.o. might bring it down.   

raymond

If you only need to know the dimensions of the image, why don't you simply extract it from the 'header' of the file itself instead of going to all the trouble of loading the file, decompressing it, loading it into a compatible DC, and then getting that same data from the DC.
Whenever you assume something, you risk being wrong half the time.
https://masm32.com/masmcode/rayfil/index.html

clamicun

That is my intention.
To get other filedata I do this...

INVOKE CreateFile,offset image_path,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0  ;filename öffnen
mov filehandle,eax

INVOKE GetFileInformationByHandle,filehandle,addr BHFI

mov eax, BHFI.nFileSizeLow
mov image_size,eax
and more.

BHFI doesn't give me the dimensions.
What do you mean with "Fileheader" ?

FORTRANS

Hi,

Quote from: clamicun on June 14, 2017, 02:56:46 AM
What do you mean with "Fileheader" ?

   Image files like *.BMP or *.GIF start with information that
describes how to decode the image.  Width, height, and number
of colors are typically part of a structure in the first part of the
file. And this is called the header of the image file.

HTH,

Steve

raymond

And, each file type will have its own structure for the information. Once you understand those structures, you can easily extract whatever info you need.
Whenever you assume something, you risk being wrong half the time.
https://masm32.com/masmcode/rayfil/index.html

Vortex

Hi clamicun,

Here is an example :

.IF uMsg==WM_CREATE

        invoke  ReadFileToMem,ADDR filename,ADDR pBitmap,\
                ADDR pNumbOfBytesRead
           
        invoke  CreateBmpFromMem,hWnd,pBitmap,ADDR hDC1
        mov     hBitmap,eax
         
    .ELSEIF uMsg==WM_PAINT

        invoke  BeginPaint,hWnd,ADDR ps
        mov     hdc,eax

        invoke  CreateCompatibleDC,eax

        mov     hMemDC,eax
        invoke  SelectObject,eax,hBitmap

        mov     ecx,pBitmap
        lea     edx,[ecx+sizeof(BITMAPFILEHEADER)] ; start of the BITMAPINFOHEADER header

        xor     eax,eax
        invoke  BitBlt,hdc,eax,eax,\
                BITMAPINFOHEADER.biWidth[edx],\
                BITMAPINFOHEADER.biHeight[edx],\
                hMemDC,eax,eax,SRCCOPY
           
        invoke  DeleteDC,hMemDC
        invoke  EndPaint,hWnd,ADDR ps


pBitmap is the pointer to the bitmap loaded to memory. The structure BITMAPINFOHEADER is what you are looking for :

typedef struct tagBITMAPINFOHEADER {
.
.
.
  LONG  biWidth;
  LONG  biHeight;
.
.
.

raymond

If you look at the header of a JPG file with a hex viewer, the first two bytes you should see (in hex format) are FF D8. If you continue to look at the header, you will notice more FF bytes followed by another byte (such as E0, DB, ...) which would be specific to describe the type of the subsequent data.The two following bytes (in bigendian format) would indicate the length of that data (including its size). The area where the FF is followed by C0 is where the dimensions of  the image are located. The height (again in bigendien format) would be in the 4th and 5th bytes following the C0, while the width would be in the 6th and 7th bytes.

Have fun. The headers of other image file types (such as GIF, BMP, ...) would be entirely different.
Whenever you assume something, you risk being wrong half the time.
https://masm32.com/masmcode/rayfil/index.html

clamicun

Thank you all, especially Ramond,
After I asked what you mean with header I started to check it out.
Think I understood.
I tested various jpgs and found height and width after offset FF C0 in the file. 

clamicun

Vortex, your eaxample.
that is exactely what I did.

And like Raymond explained, it's much faster to read the header. I have to open the file anyway for "GetFileInformationByHandle" ... And even that might  be unnecessary ...  ? maybe all information is in the header ...

clamicun

No, it is not that simple.
There are jpgs without offset FF C0.
Where to look there ?

TWell

http://www.fileformat.info/format/jpeg/egff.htm

jj2007


TWell

https://en.wikipedia.org/wiki/JPEG
QuoteSOF2   0xFF, 0xC2   variable size   Start Of Frame (progressive DCT)   Indicates that this is a progressive DCT-based JPEG, and specifies the width, height, number of components, and component subsampling (e.g., 4:2:0).

00000090                                            ff c2                ÿÂ
000000a0  00 11 08 02 ad 01 d4 03 01 22 00 02 11 01 03 11  ....­.Ô.."......
000000b0  01                                               .


00000000  ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 01  ÿØÿà..JFIF......
00000010  00 01 00 00 ff db 00 43 00 0a 07 07 08 07 06 0a  ....ÿÛ.C........
00000020  08 08 08 0b 0a 0a 0b 0e 18 10 0e 0d 0d 0e 1d 15  ................
00000030  16 11 18 23 1f 25 24 22 1f 22 21 26 2b 37 2f 26  ...#.%$"."!&+7/&
00000040  29 34 29 21 22 30 41 31 34 39 3b 3e 3e 3e 25 2e  )4)!"0A149;>>>%.
00000050  44 49 43 3c 48 37 3d 3e 3b ff db 00 43 01 0a 0b  DIC<H7=>;ÿÛ.C...
00000060  0b 0e 0d 0e 1c 10 10 1c 3b 28 22 28 3b 3b 3b 3b  ........;("(;;;;
00000070  3b 3b 3b 3b 3b 3b 3b 3b 3b 3b 3b 3b 3b 3b 3b 3b  ;;;;;;;;;;;;;;;;
00000080  3b 3b 3b 3b 3b 3b 3b 3b 3b 3b 3b 3b 3b 3b 3b 3b  ;;;;;;;;;;;;;;;;
00000090  3b 3b 3b 3b 3b 3b 3b 3b 3b 3b 3b 3b 3b 3b ff c2  ;;;;;;;;;;;;;;ÿÂ
000000a0  00 11 08 02 ad 01 d4 03 01 22 00 02 11 01 03 11  ....­.Ô.."......
000000b0  01 ff c4 00 1b 00 00 02 03 01 01 01 00 00 00 00  .ÿÄ.............
000000c0  00 00 00 00 00 00 00 01 02 03 04 05 06 07 ff c4  ..............ÿÄ
000000d0  00 19 01 01 01 01 01 01 01 00 00 00 00 00 00 00  ................
000000e0  00 00 00 00 01 02 03 04 05 ff da 00 0c 03 01 00  .........ÿÚ.....

clamicun

Thanks TWell,
so it is not safe to only check for FF C0

Vortex

Quote from: clamicun on June 14, 2017, 07:30:01 AM
Vortex, your eaxample.
that is exactely what I did.

No, not exactly the same.

Quote
And like Raymond explained, it's much faster to read the header. I have to open the file anyway for "GetFileInformationByHandle" ... And even that might  be unnecessary ...  ? maybe all information is in the header ...

My example above follows Raymond's method. You don't need the API GetFileInformationByHandle. Maybe, my example was not clear. Another example :

include     GetBmpSize.inc

.data

msg1        db 'Usage : GetBmpSize.exe bitmapfile.bmp',13,10,0
msg2        db 'Width = %u',13,10
            db 'Height = %u',0

.data?

buffer1     db 512 dup(?)
buffer2     db 512 dup(?)

.code

start:

    call    main
    invoke  ExitProcess,0

main PROC uses esi
       
LOCAL pMem:DWORD
LOCAL BytesRead:DWORD

    mov     esi,OFFSET buffer1
    invoke  ParseCmdLine,esi
    cmp     eax,1+1
    je      @f
       
    invoke  StdOut,ADDR msg1
    ret
@@:
    lea     ecx,BytesRead
    invoke  ReadFileToMem,DWORD PTR [esi+4],
            ADDR pMem,ecx

    mov     eax,pMem
    add     eax,sizeof(BITMAPFILEHEADER)

    invoke  wsprintf,ADDR buffer2,ADDR msg2,\
            BITMAPINFOHEADER.biWidth[eax],
            BITMAPINFOHEADER.biHeight[eax]

    invoke  StdOut,ADDR buffer2

    invoke  VirtualFree,pMem,0,MEM_RELEASE
    ret

main ENDP

END start


Testing the application :

GetBmpSize.exe Test.bmp
Width = 119
Height = 82


Quote
Bitmap-File Structures

Each bitmap file contains a bitmap-file header, a bitmap-information header,
a color table, and an array of bytes that defines the bitmap bits. The file
has the following form:

BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;
RGBQUAD          aColors[];
BYTE             aBitmapBits[];

The bitmap-file header contains information about the type, size, and layout
of a device-independent bitmap file. The header is defined as a
BITMAPFILEHEADER structure.

The bitmap-information header, defined as a BITMAPINFOHEADER structure,
specifies the dimensions, compression type, and color format for the bitmap.

http://www.martinreddy.net/gfx/2d/BMP.txt