Jump to content
Sign in to follow this  
tobi95

how to save binary image to file

Recommended Posts

tobi95

i want to download a pic with _Inetgetsource and save it as an image. e.g. $pic=_Inetgetsource("http://www.autoitscript.com/site/wp-content/themes/TheCorporation/images/logo.png")

1. do i have to use the binary flag ("False") with _Inetgetsource ? i think yes

2. how do i save the data in $pic to a file e.g. c:\logo.png ?

i have done that before, but i forgot how :oops: thanx in advance

btw: i do not want to use Inetget() for certain reasons.

Share this post


Link to post
Share on other sites
tobi95

something like:

$pic=_INetGetSource("http://www.autoitscript.com/site/wp-content/themes/TheCorporation/images/logo.png",False)
$open=FileOpen("c:logo.png",18)
FileWrite($open,$pic)
FileClose($open)

but no matter how i put it, it does not show.

Edited by tobi95

Share this post


Link to post
Share on other sites
DW1

You can simply write the data to a file:

#include <Inet.au3>
$bData = _INetGetSource('http://www.autoitscript.com/site/wp-content/themes/TheCorporation/images/logo.png', False)
$hFile = FileOpen(@DesktopDir & 'test.png', 2 + 16)
FileWrite($hFile, $bData)
FileClose($hFile)

EDIT: just saw your second post that you made while I was posting this.

Both your code, and my code work when I test them (they are pretty much the same).

If this is Vista+ try adding #RequireAdmin to the top of the script?

Edited by danwilli

Share this post


Link to post
Share on other sites
tobi95

ooops no i have win xp. this works ?

Share this post


Link to post
Share on other sites
tobi95

no, it does not work for me. test.png is an empty file. 0 bytes. somehow the binary data has to be converted.

Edited by tobi95

Share this post


Link to post
Share on other sites
DW1

tobi95, what are you seeing, no file gets created? Is _InetGetSource() failing? Add some error checking and see where it is failing.

Share this post


Link to post
Share on other sites
tobi95

_inetgetsource does not fail. i can see the data with msgbox. but the file created stays empty. this is crazy. does it really work for you ?

Edited by tobi95

Share this post


Link to post
Share on other sites
DW1

_inetgetsource does not fail. i can see the data with msgbox. but the file created stays empty. this is crazy. does it really work for you ?

Yes, it really does work for me, I am on 32-bit XP also. test.png is 16,200 bytes

EDIT: Does FileOpen() or FileWrite() error out?

Edited by danwilli

Share this post


Link to post
Share on other sites
tobi95

strange. so strange. this is my _inetgetsource:

Func _INetGetSource($s_URL, $s_Header = '')
If StringLeft($s_URL, 7) <> 'http://' And StringLeft($s_URL, 8) <> 'https://' Then $s_URL = 'http://' & $s_URL
Local $h_DLL = DllOpen("wininet.dll")
Local $ai_IRF, $s_Buf = ''
Local $ai_IO = DllCall($h_DLL, 'int', 'InternetOpen', 'str', "AutoIt v3", 'int', 0, 'int', 0, 'int', 0, 'int', 0)
If @error Or $ai_IO[0] = 0 Then
  DllClose($h_DLL)
  SetError(1)
  Return ""
EndIf
Local $ai_IOU = DllCall($h_DLL, 'int', 'InternetOpenUrl', 'int', $ai_IO[0], 'str', $s_URL, 'str', $s_Header, 'int', StringLen($s_Header), 'int', 0x80000000, 'int', 0)
If @error Or $ai_IOU[0] = 0 Then
  DllCall($h_DLL, 'int', 'InternetCloseHandle', 'int', $ai_IO[0])
  DllClose($h_DLL)
  SetError(1)
  Return ""
EndIf
Local $v_Struct = DllStructCreate('udword')
DllStructSetData($v_Struct, 1, 1)
While DllStructGetData($v_Struct, 1) <> 0
  $ai_IRF = DllCall($h_DLL, 'int', 'InternetReadFile', 'int', $ai_IOU[0], 'str', '', 'int', 256, 'ptr', DllStructGetPtr($v_Struct))
  $s_Buf &= StringLeft($ai_IRF[2], DllStructGetData($v_Struct, 1))
WEnd
DllCall($h_DLL, 'int', 'InternetCloseHandle', 'int', $ai_IOU[0])
DllCall($h_DLL, 'int', 'InternetCloseHandle', 'int', $ai_IO[0])
DllClose($h_DLL)
Return $s_Buf
EndFunc   ;==>_INetGetSource

it must work. but it does not.

Share this post


Link to post
Share on other sites
tobi95

Yes, it really does work for me, I am on 32-bit XP also. test.png is 16,200 bytes

EDIT: Does FileOpen() or FileWrite() error out?

no @errors. the file is created. but empty.

Share this post


Link to post
Share on other sites
ProgAndy

You should update to the most recent stable of AutoIt (it uses InetRead in _InetGetSource which is now a mere wrapper)

By the way, what reason do you have to use _InetGetSource + FileWrite instead of InetGet?

Edited 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

Share this post


Link to post
Share on other sites
tobi95

@progandy: downloading 4000 files, inetget gets incredibly slow and temp internetfiles is full. i wanted to try the other method without temp file.

ok so my include may be outdated. is InetRead() better ?

Edited by tobi95

Share this post


Link to post
Share on other sites
UEZ

Have a look here how to download an image from web and display it directly into the GUI without saving it to the disk first:

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites
tobi95

ty all, i tried it all day long and couldn't explain myself what was wrong. :oops:

Share this post


Link to post
Share on other sites
DW1

So it is working now on the latest version of AutoIt?

Share this post


Link to post
Share on other sites
tobi95

So it is working now on the latest version of AutoIt?

yes, but i have to test if it behaves better with thousands of files. i really hope so. thank you

ok, tested it and i have to say, InetRead is as slow as Inetget when it comes to lots of files,and it creates temp files as well. i hoped it worked better :oops: very disappointed.

now i will try the WinINet Functions but that is the same as my old and faulty _InetGetSource method i fear. *sigh*

Edited by tobi95

Share this post


Link to post
Share on other sites
tobi95

the adapted script from the above link does not work either. same problem as before.

#include <Math.au3>
$jDll = DllOpen("Wininet.dll")
$Buffer = Inet_Read('http://www.autoitscript.com/site/wp-content/themes/TheCorporation/images/logo.png',100)
MsgBox(0,"",@error)
$Of = FileOpen("test.png",2)
FileWrite($Of,Binary(DllStructGetData($Buffer,1)))
FileClose($Of)
Func Inet_Read($lpszUrl,$ByteAtaTime)
if ($ByteAtaTime <= 0) Then Return SetError(1,0,0)
$HIntOpen = InternetOpen("OPEN")
if Not ($HIntOpen) Then Return SetError(2,0,0)
$HIntOpenUrl = InternetOpenUrl($HIntOpen,$lpszUrl,"",0,0,0)
if Not ($HIntOpenUrl) Then Return SetError(3,0,0)
$FileSize = HttpQueryInfo($HIntOpenUrl,5)
if @error Then Return SetError(4,0,0)
$Buffer = DllStructCreate("BYTE[" & $FileSize & "]")
$lpBuffer = DllStructGetPtr($Buffer)
Local $MovePos = 0
$FileSize = Number($FileSize)
While 1
$OutPtr = $lpBuffer + $MovePos
$dwNumberOfBytesToRead = _Min($ByteAtaTime,$FileSize - $MovePos);
$lpdwNumberOfBytesRead = InternetReadFile($HIntOpenUrl,$OutPtr,$dwNumberOfBytesToRead)
$error = @error
if $error Or $lpdwNumberOfBytesRead <= 0 Then ExitLoop
$MovePos += $lpdwNumberOfBytesRead
WEnd
if ($error) Then $error = 5
InternetCloseHandle($HIntOpen)
InternetCloseHandle($HIntOpenUrl)
Return SetError($error,0,$Buffer)
EndFunc
Func InternetReadFile($hFile,$lpBuffer,$dwNumberOfBytesToRead)
$DLLSDWORD = DllStructCreate("DWORD")
$lpdwNumberOfBytesRead = DllStructGetPtr($DLLSDWORD)
$BOOL = DllCall($jDll,"BOOL","InternetReadFile","HANDLE",$hFile,"ptr",$lpBuffer, _
"DWORD",$dwNumberOfBytesToRead,"ptr",$lpdwNumberOfBytesRead)
if @error Or $BOOL[0] = 0 Then Return SetError(1,0,0)
Return SetError(0,0,DllStructGetData($DLLSDWORD,1))
EndFunc
Func HttpQueryInfo($hRequest,$dwInfoLevel,$lpdwIndex = 0)
Local $lpdwBufferLength = 1000
$DLLSDWORD = DllStructCreate("DWORD")
DllStructSetData($DLLSDWORD,1,$lpdwBufferLength)
$LPDWORDLENGTH = DllStructGetPtr($DLLSDWORD)
$DLLSlpvBuffer = DllStructCreate("WCHAR[" & $lpdwBufferLength & "]")
$lpvBuffer = DllStructGetPtr($DLLSlpvBuffer)
$BOOL = DllCall($jDll,"BOOL","HttpQueryInfoW","HANDLE",$hRequest,"DWORD",$dwInfoLevel, _
"ptr",$lpvBuffer,"ptr",$LPDWORDLENGTH,"DWORD",$lpdwIndex)
if @error Or $BOOL[0] = 0 Then Return SetError(1,0,0)
Return SetError(0,0,DllStructGetData($DLLSlpvBuffer,1))
EndFunc
Func InternetOpenUrl($hInternet,$lpszUrl,$lpszHeaders,$dwHeadersLength,$dwFlags,$dwContext)
$HINTERNET = DllCall($jDll,"HANDLE","InternetOpenUrlW","HANDLE",$hInternet,"wstr",$lpszUrl, _
"wstr",$lpszHeaders,"DWORD",$dwHeadersLength,"DWORD",$dwFlags,"ptr",$dwContext)
if @error Then Return SetError(1,0,0)
if Not ($HINTERNET[0]) Then Return SetError(2,0,0)
Return SetError(0,0,$HINTERNET[0])
EndFunc
Func InternetOpen($lpszAgent,$dwAccessType = 0,$lpszProxyName = "",$lpszProxyBypass = "",$dwFlags = 0)
$HINTERNET = DllCall($jDll,"HANDLE","InternetOpenW","wstr",$lpszAgent,"DWORD",$dwAccessType, _
"wstr",$lpszProxyName,"wstr",$lpszProxyBypass,"DWORD",$dwFlags)
if @error Then Return SetError(1,0,0)
if Not ($HINTERNET[0]) Then Return SetError(2,0,0)
Return SetError(0,0,$HINTERNET[0])
EndFunc
Func InternetCloseHandle($hInternet)
$BOOL = DllCall($jDll,"BOOL","InternetCloseHandle","HANDLE",$hInternet)
if @error Or $BOOL[0] = 0 Then Return SetError(1,0,0)
Return SetError(0,0,$BOOL[0])
EndFunc

now i am really puzzled why wininet functions fail with the test.png

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×