Jump to content

how to save binary image to file


Recommended Posts

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.

Link to comment
Share on other sites

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
Link to comment
Share on other sites

_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
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

@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
Link to comment
Share on other sites

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...