网页中的png图片直截保存体积很小,用这种au3方法保存却很大[已解决]
本帖最后由 ccxw1983 于 2010-10-8 09:14 编辑我的目的是:在打开一个有图片的页面后,再用au3程序保存页面的图片到本地,希望au3保存的图片的大小和手工保存的一样大。
现在只找到下面这种方式可以保存网页中的图片,但是这种方式保存的图片比较大,并且用了粘贴板,在保存图片的过程中我再用粘贴板的话可能造成程序运行错误,程序用InetGet的方式又不合适(google book的一些限制会导致下载效果不好,用页面的话可以从缓存读取图片)。
希望高手们赐教!
#include <GDIPlus.au3>
#include <ScreenCapture.au3>
#include <IE.au3>
#include <GuiConstantsEx.au3>
#include <ClipBoard.au3>
#include <WindowsConstants.au3>
;浏览器中浏览图片
;http://books.google.com.hk/books?id=CHswO9obwk8C&pg=PR5&img=1&zoom=3&hl=zh-CN&sig=ACfU3U2fo1zQrISnmSnUuXmvCad8n9ygMA&w=1025
;另存为才142k
;这样保存却有526k
;为什么?
Opt('MustDeclareVars', 1)
Local $f = @ScriptDir & "\ask_test_1.html"
If FileExists($f) == 0 Then
FileWrite($f, "<html> <head><title>Googlebook</title></head> <body> <imgborder=1 src=http://books.google.com.hk/books?id=CHswO9obwk8C&pg=PR5&img=1&zoom=3&hl=zh-CN&sig=ACfU3U2fo1zQrISnmSnUuXmvCad8n9ygMA&w=1025/> </body> </html>")
Sleep(1000)
EndIf
Local $oIE = _IECreate($f)
Sleep(1000)
setClipboard()
Sleep(1000)
_Main()
Func _Main()
Local $hBitmap, $hImage, $sCLSID, $tData, $tParams
_GDIPlus_Startup()
_ClipBoard_Open(0)
$hImage = _ClipBoard_GetDataEx($CF_BITMAP);$CF_BITMAP ;$CF_METAFILEPICT
If $hImage == 0 Then
MsgBox(0, "", "粘贴板没找到")
Else
$hImage = _GDIPlus_BitmapCreateFromHBITMAP($hImage)
$sCLSID = _GDIPlus_EncodersGetCLSID("PNG")
Local $tt = @ScriptDir & "\GDIPlus_Image2.jpg"
ConsoleWrite($tt & @CRLF)
_GDIPlus_ImageSaveToFileEx($hImage, $tt, $sCLSID)
_ClipBoard_Close()
EndIf
_GDIPlus_Shutdown()
EndFunc ;==>_Main
;设置粘贴板
Func setClipboard()
Local $oIE = _IEAttach("Googlebook")
If @error = 0 Then
Local $oImgs = _IEImgGetCollection($oIE)
For $oImg In $oImgs
;复制图片
Local $oPic = $oIE.Document.body.createControlRange()
$oPic.Add($oImg)
$oPic.execCommand("Copy")
MsgBox(0, "", "图片复制了", 2)
ExitLoop
Next
Else
MsgBox(0, "", "html测试页码没找到", 2)
EndIf
EndFunc ;==>setClipboard
本帖最后由 republican 于 2010-10-7 07:32 编辑
#include <Array.au3>
#include <WinHttp_GetRespond.au3>
$MyOpen=_WinHttpOpen()
$rContext=_WinHTTP_GetRespond($MyOpen,"http://books.google.com.hk/books?id=CHswO9obwk8C&pg=PR5&img=1&zoom=3&hl=zh-CN&sig=ACfU3U2fo1zQrISnmSnUuXmvCad8n9ygMA&w=1025",0,2)
FileWrite(@ScriptDir & "\5.jpeg",Binary($rContext))
_WinHttpCloseHandle($MyOpen)
google book有什么限制呢?
保存文件大是因为你使用GDI重新渲染了。 回复 2# republican
这样和InetGet差不多吧?仍然是直截连服务器去下载的吧?如果是调用浏览器下载的话或许还可能从缓存里面取的数据。
google book是这样的,这个图片的url,这会儿能够访问,待会儿可能就不能访问了,用浏览器去下载是为了能够从缓存里面取到文件。
如果能够直截复制浏览器的临时文件夹的文件的话,更好,我是找不到方法,才想到这种间接的方式的。 这个是获取指定URL在缓存里的路径问题吧,可以看看这个,我不懂~
http://hi.baidu.com/lbird/blog/item/87d81108cf541238e8248808.html 其实InetGet就可以用缓存的了。 本帖最后由 republican 于 2010-10-7 17:10 编辑
回复 4# afan
原来是wininet的成员,这就简单了,有现成的UDF.
#include <WinINet.au3>
$Test=_WinINet_GetUrlCacheEntryInfo("http://books.google.com.hk/books?id=CHswO9obwk8C&pg=PR5&img=1&zoom=3&hl=zh-CN&sig=ACfU3U2fo1zQrISnmSnUuXmvCad8n9ygMA&w=1025")
If Not @error Then
ShellExecute($Test)
Else
MsgBox(0,"Error",@error)
EndIf
忘了说,wininet库有点旧了,需要对$AU3_UNICODE进行修改。
编译好的文件:
回复 6# republican
要修改什么地方么? 我这没修改也正常啊 我也刚看到 WinINet 的东东,不过用http://www.autoitx.com/forum.php?mod=viewthread&tid=16575&highlight=Wininet的附件的东西会报错:
+>18:02:05 Starting AutoIt3Wrapper v.2.0.1.24 Environment(Language:0804Keyboard:00000804OS:WIN_7/CPU:X64 OS:X86)
>Running AU3Check (1.54.19.0)from:C:\Program Files\AutoIt3
C:\Users\lenovo\Downloads\WinINet_2010_01_02\WinINetConstants.au3(5,102) : ERROR: undefined macro.
Global Const $AU3_UNICODE = Number($AU3_VERSION & "." & $AU3_VERSION) >= 2.13 Or @AutoItUnicode 我修改了WinINetConstants.au3的这行
Global Const $AU3_UNICODE = Number($AU3_VERSION & "." & $AU3_VERSION) >= 2.13 Or @AutoItUnicode
去掉了
Or @AutoItUnicode
可以运行了。
在帮助文档里面有说明:
16th May, 2008 - v3.2.12.0
AutoIt:
Changed: @Unicode renamed to @AutoItUnicode. @Unicode is an alias for now. It will be removed > 3.2.14.0 回复 2# republican
谢谢,我已按照这种方式搞定。 回复 7# afan
同8-9楼的问题。 回复 11# republican
那个不算问题吧,SciTE的报错也鸟它? 回复 12# afan
@AutoItUnicode 本身就不存在,程序不可能运行的。
退出代码: :2 回复afan
@AutoItUnicode 本身就不存在,程序不可能运行的。
退出代码: :2
republican 发表于 2010-10-7 19:14 http://www.autoitx.com/images/common/back.gif
直接运行 MsgBox(0, 0, @AutoItUnicode) 试试 回复 14# afan
不好意思,刚才编译错文件了,所以才有此结论。
代码少的话,可以直接忽略sicte的报错。
但我不认为忽略sicte的错误报错对写一个“大型程序”有多大帮助,你仍然需要从错误中分辨哪些是正确的报错,哪些是不用管的,所以对于isdeclare类的报错我通常都遵循sicte,这样会省下很多无谓的思考。
页:
[1]
2