monoceres Posted May 1, 2008 Share Posted May 1, 2008 (edited) Hi! I need to fill a BITMAPINFOHEADER structure (Exactly like $tagBITMAPINFO except the RGBQuad element), and I'm completely lost. The delphi source I'm translating did this by using BlockRead from the bitmap directly to the struct (Me thinks that delphi is very strange), but this doesn't seem like something autoit can handle. Any ideas? Edited May 1, 2008 by monoceres Broken link? PM me and I'll send you the file! Link to comment Share on other sites More sharing options...
weaponx Posted May 1, 2008 Share Posted May 1, 2008 You may want to take a look at this script, it contains references to RGBQUAD, BITMAPINFO, and BITMAPINFOHEADER:http://www.autoitscript.com/forum/index.ph...mp;#entry213739 Link to comment Share on other sites More sharing options...
monoceres Posted May 1, 2008 Author Share Posted May 1, 2008 You may want to take a look at this script, it contains references to RGBQUAD, BITMAPINFO, and BITMAPINFOHEADER: http://www.autoitscript.com/forum/index.ph...mp;#entry213739 I have been looking at this code, but it seems like its only writing files, not reading them. I have found a c++ example, so maybe as a last resort I could create a small dll... but it would be really great to have this done in autoit, I mean the info is in there! You just have to know where to look. Here's how delphi did it, maybe someone will get a flash of genious AssignFile(BFile,"1.bmp"); Reset(BFile,1); BlockRead(BFile,m_Bfh,SizeOf(m_Bfh)); // m_Bfh= BITMAPFILEHEADER, m_Bih=BITMAPINFOHEADER BlockRead(BFile,m_Bih,SizeOf(m_Bih)); SetLength(m_MemBitMapInfo,m_bfh.bfOffBits - 14); SetLength(m_MemBits,m_Bih.biSizeImage); Seek(BFile,SizeOf(m_Bfh)); BlockRead(BFile,m_MemBitMapInfo[0],length(m_MemBitMapInfo)); CloseFile(BFile); Any input is greatly appreciated since this has stopped my entire project Broken link? PM me and I'll send you the file! Link to comment Share on other sites More sharing options...
ProgAndy Posted May 1, 2008 Share Posted May 1, 2008 (edited) Pseudo-Code: #Include <WinAPI.au3> $hFile = _WinAPI_CreateFile("the.bmp",1,2) $m_Bfh= DllstructCreate(BITMAPFILEHEADER) _WinAPI_ReadFile($hFile,DllstructGetPtr($m_Bfh),DllStructGetSize($m_Bfh)) $m_Bih= DllstructCreate(BITMAPINFOHEADER) _WinAPI_ReadFile($hFile,DllstructGetPtr($m_Bih),DllStructGetSize($m_Bih)) ;Now $_Bih is BITMAPINFOHEADER Edited May 1, 2008 by ProgAndy *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes Link to comment Share on other sites More sharing options...
monoceres Posted May 1, 2008 Author Share Posted May 1, 2008 Pseudo-Code: #Include <WinAPI.au3> $hFile = _WinAPI_CreateFile("the.bmp",1,2) $m_Bfh= DllstructCreate(BITMAPFILEHEADER) _WinAPI_ReadFile($hFile,DllstructGetPtr($m_Bfh),DllStructGetSize($m_Bfh)) $m_Bih= DllstructCreate(BITMAPINFOHEADER) _WinAPI_ReadFile($hFile,DllstructGetPtr($m_Bih),DllStructGetSize($m_Bih)) ;Now $_Bih is BITMAPINFOHEADERThanks for your answer but it doesn't seem to work, all elements in the struct are 0... but I definitly think you're on the right track! Broken link? PM me and I'll send you the file! Link to comment Share on other sites More sharing options...
monoceres Posted May 1, 2008 Author Share Posted May 1, 2008 Now I see why it only returns 0, it because _WinApi_createfile() overwrites my bitmap, but I still need the handle returned from it. Why is there not a _WinApi_OpenFile()? FileOpen() doesn't seem to work... Broken link? PM me and I'll send you the file! Link to comment Share on other sites More sharing options...
weaponx Posted May 1, 2008 Share Posted May 1, 2008 Now I see why it only returns 0, it because _WinApi_createfile() overwrites my bitmap, but I still need the handle returned from it. Why is there not a _WinApi_OpenFile()? FileOpen() doesn't seem to work... #Include <WinAPI.au3> _WinAPI_CreateFile($sFileName, $iCreation[, $iAccess = 4[, $iShare = 0[, $iAttributes = 0[, $pSecurity = 0]]]]) $iCreation Action to take on files that exist and do not exist: 0 - Creates a new file. The function fails if the file exists 1 - Creates a new file. If a file exists, it is overwritten 2 - Opens a file. The function fails if the file does not exist 3 - Opens a file. If the file does not exist, the function creates the file 4 - Opens a file and truncates it so that its size is 0 bytes. The function fails if the file does not exist. $iAccess Access to the object: 1 - Execute 2 - Read 4 - Write $iShare Sharing mode of an object: 1 - Delete 2 - Read 4 - Write $hFile = _WinAPI_CreateFile("the.bmp",2,2,2) Link to comment Share on other sites More sharing options...
monoceres Posted May 1, 2008 Author Share Posted May 1, 2008 Aah I see, but I'm still having problems My struct is now filled but it has real strange values, for example this returns that biWidth=10. #Include <WinAPI.au3> $BITMAPINFOHEADER = DllStructCreate("dword biSize;dword biWidth;dword biHeight;ushort biPlanes;ushort biBitCount;dword biCompression;dword biSizeImage;dword biXPelsPerMeter;dword biYPelsPerMeter;dword biClrUsed;dword biClrImportant") $m_Bih=$BITMAPINFOHEADER $hFile = _WinAPI_CreateFile("3.bmp",2,2,2) Dim $readbytes _WinAPI_ReadFile($hFile,DllstructGetPtr($m_Bih),DllStructGetSize($m_Bih),$readbytes) MsgBox(0,"",DllStructGetData($m_Bih,"biWidth")) Thanks for your time Broken link? PM me and I'll send you the file! Link to comment Share on other sites More sharing options...
weaponx Posted May 1, 2008 Share Posted May 1, 2008 I don't know man I was having similar problems with those functions yesterday in this topic:http://www.autoitscript.com/forum/index.php?showtopic=70124 Link to comment Share on other sites More sharing options...
monoceres Posted May 1, 2008 Author Share Posted May 1, 2008 I don't know man I was having similar problems with those functions yesterday in this topic:http://www.autoitscript.com/forum/index.php?showtopic=70124That's too bad, I'm almost done with my function, it's a BitmapsToAvi function and this is the only thing left, I have succesfully created both file and stream.Anyways I just need the values in the struct, maybe there is another way to query them? I currently use GetExtProperty() udf to get the width and height of bitmap, but it won't return any of the other more advanced info. Broken link? PM me and I'll send you the file! Link to comment Share on other sites More sharing options...
zorphnog Posted May 1, 2008 Share Posted May 1, 2008 Based on the Delphi code and the bitmap file format (http://en.wikipedia.org/wiki/BMP_file_format), you need to read the file header before you read the info header so that the file pointer will be in the correct position.#Include <WinAPI.au3> Global Const $tagBITMAPFILEHEADER = "ushort bfType;dword bfSize;ushort bfReserved1;ushort bfReserved2;dword bfOffBits" Global Const $tagBITMAPINFOHEADER = "dword biSize;dword biWidth;dword biHeight;ushort biPlanes;" & _ "ushort biBitCount;dword biCompression;dword biSizeImage;dword biXPelsPerMeter;dword biYPelsPerMeter;" & _ "dword biClrUsed;dword biClrImportant" $m_Bfh = DllStructCreate($tagBITMAPFILEHEADER) $m_Bih = DllStructCreate($tagBITMAPINFOHEADER) $hFile = _WinAPI_CreateFile(@ScriptDir & "\on.bmp",2,2,2) If $hFile = 0 Then ConsoleWrite("! Failed to open file" & @LF) Exit EndIf Dim $readbytes If _WinAPI_ReadFile($hFile,DllStructGetPtr($m_Bfh),DllStructGetSize($m_Bfh),$readbytes) Then _ ConsoleWrite("+ readbytes = " & $readbytes & @LF) If _WinAPI_ReadFile($hFile,DllstructGetPtr($m_Bih),DllStructGetSize($m_Bih),$readbytes) Then _ ConsoleWrite("+ readbytes = " & $readbytes & @TAB & "biWidth = " & DllStructGetData($m_Bih,"biWidth") & @LF) Link to comment Share on other sites More sharing options...
monoceres Posted May 1, 2008 Author Share Posted May 1, 2008 Based on the Delphi code and the bitmap file format (http://en.wikipedia.org/wiki/BMP_file_format), you need to read the file header before you read the info header so that the file pointer will be in the correct position. #Include <WinAPI.au3> Global Const $tagBITMAPFILEHEADER = "ushort bfType;dword bfSize;ushort bfReserved1;ushort bfReserved2;dword bfOffBits" Global Const $tagBITMAPINFOHEADER = "dword biSize;dword biWidth;dword biHeight;ushort biPlanes;" & _ "ushort biBitCount;dword biCompression;dword biSizeImage;dword biXPelsPerMeter;dword biYPelsPerMeter;" & _ "dword biClrUsed;dword biClrImportant" $m_Bfh = DllStructCreate($tagBITMAPFILEHEADER) $m_Bih = DllStructCreate($tagBITMAPINFOHEADER) $hFile = _WinAPI_CreateFile(@ScriptDir & "\on.bmp",2,2,2) If $hFile = 0 Then ConsoleWrite("! Failed to open file" & @LF) Exit EndIf Dim $readbytes If _WinAPI_ReadFile($hFile,DllStructGetPtr($m_Bfh),DllStructGetSize($m_Bfh),$readbytes) Then _ ConsoleWrite("+ readbytes = " & $readbytes & @LF) If _WinAPI_ReadFile($hFile,DllstructGetPtr($m_Bih),DllStructGetSize($m_Bih),$readbytes) Then _ ConsoleWrite("+ readbytes = " & $readbytes & @TAB & "biWidth = " & DllStructGetData($m_Bih,"biWidth") & @LF)Now I get that width=23265280 which is also a bit strange... I mean the code is almost like the delphi code now, should work. Thanks for your input though Broken link? PM me and I'll send you the file! Link to comment Share on other sites More sharing options...
weaponx Posted May 1, 2008 Share Posted May 1, 2008 You need to seperate the hiword and loword from the return. ConsoleWrite(_WinAPI_HiWord(DllStructGetData($m_Bih,"biWidth")) & @CRLF) Link to comment Share on other sites More sharing options...
monoceres Posted May 1, 2008 Author Share Posted May 1, 2008 You need to seperate the hiword and loword from the return.ConsoleWrite(_WinAPI_HiWord(DllStructGetData($m_Bih,"biWidth")) & @CRLF) I love you guys, seriously Thanks so much for this, now I can finally finish my function and when I release it, well expect huge "thank to" credits Broken link? PM me and I'll send you the file! Link to comment Share on other sites More sharing options...
weaponx Posted May 1, 2008 Share Posted May 1, 2008 My test image is 1024x768 but the width comes back as 768 and the height is 1, anyone else? Link to comment Share on other sites More sharing options...
monoceres Posted May 1, 2008 Author Share Posted May 1, 2008 My test image is 1024x768 but the width comes back as 768 and the height is 1, anyone else?Unfortunetly Yes, I get the same result, maybe offsetting the read position? Broken link? PM me and I'll send you the file! Link to comment Share on other sites More sharing options...
monoceres Posted May 1, 2008 Author Share Posted May 1, 2008 Ok I managed to get the right values of biWidth and biHeight by reading one less dword from the first _WinApi_FileRead, but I don't know about the other values. Broken link? PM me and I'll send you the file! Link to comment Share on other sites More sharing options...
zorphnog Posted May 2, 2008 Share Posted May 2, 2008 I believe you have to use the offset value from the file header, but I'm not sure how to use it. I've noticed that it seems to be off by just the first dword value so you could reset the file pointer like this to try and read it: #Include <WinAPI.au3> Global Const $tagBITMAPFILEHEADER = "ushort bfType;dword bfSize;ushort bfReserved1;ushort bfReserved2;dword bfOffBits" Global Const $tagBITMAPINFOHEADER = "dword biSize;dword biWidth;dword biHeight;ushort biPlanes;" & _ "ushort biBitCount;dword biCompression;dword biSizeImage;dword biXPelsPerMeter;dword biYPelsPerMeter;" & _ "dword biClrUsed;dword biClrImportant" $m_Bfh = DllStructCreate($tagBITMAPFILEHEADER) $m_Bih = DllStructCreate($tagBITMAPINFOHEADER) $hFile = _WinAPI_CreateFile(@ScriptDir & "\bpong.bmp",2,2,2) If $hFile = 0 Then ConsoleWrite("! Failed to open file" & @LF) Exit EndIf Dim $readbytes If _WinAPI_ReadFile($hFile,DllStructGetPtr($m_Bfh),DllStructGetSize($m_Bfh),$readbytes) Then _ ConsoleWrite("+ readbytes = " & $readbytes & @TAB & "bfOffBits = " & _WinAPI_HiWord(DllStructGetData($m_Bfh, "bfOffBits")) & @LF) $aResult = DllCall("kernel32.dll", "int", "SetFilePointerEx", "hwnd", $hFile, "uint64", -4, "long*", 0, "int", 1) If $aResult[0] = 0 Then Exit If _WinAPI_ReadFile($hFile,DllstructGetPtr($m_Bih),DllStructGetSize($m_Bih),$readbytes) Then _ ConsoleWrite("+ readbytes = " & $readbytes & @LF) Link to comment Share on other sites More sharing options...
monoceres Posted May 2, 2008 Author Share Posted May 2, 2008 Thanks for all yur help in this. Really appreciate it, but this is not going to work. I have now at long long last set the format of the stream but now I have to write the bitmaps to the avi stream which means advanced file reading, buffers to data and other things I don't think I can fix. As I said before really thanks for your help and if anyone is curious, here's the complete super messy code in which I failed Also includes delphi code: avi.au3 It's a real shame this doesn't worked out, could have created some cool stuff with it. Like a screenrecorder an such. Broken link? PM me and I'll send you the file! Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now