找回密码
 加入
搜索
查看: 12775|回复: 18

[图形处理] 网页中的png图片直截保存体积很小,用这种au3方法保存却很大[已解决]

 火.. [复制链接]
发表于 2010-10-6 21:34:14 | 显示全部楼层 |阅读模式
本帖最后由 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> <img  border=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
发表于 2010-10-7 07:31:06 | 显示全部楼层
本帖最后由 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[0]))
_WinHttpCloseHandle($MyOpen) 


google book有什么限制呢?


保存文件大是因为你使用GDI重新渲染了。

评分

参与人数 1金钱 +25 收起 理由
afan + 25

查看全部评分

 楼主| 发表于 2010-10-7 15:10:06 | 显示全部楼层
回复 2# republican

这样和InetGet差不多吧?仍然是直截连服务器去下载的吧?如果是调用浏览器下载的话或许还可能从缓存里面取的数据。
google book是这样的,这个图片的url,这会儿能够访问,待会儿可能就不能访问了,用浏览器去下载是为了能够从缓存里面取到文件。
如果能够直截复制浏览器的临时文件夹的文件的话,更好,我是找不到方法,才想到这种间接的方式的。
发表于 2010-10-7 15:23:26 | 显示全部楼层
这个是获取指定URL在缓存里的路径问题吧,可以看看这个,我不懂~
http://hi.baidu.com/lbird/blog/item/87d81108cf541238e8248808.html
发表于 2010-10-7 17:07:04 | 显示全部楼层
其实InetGet就可以用缓存的了。
发表于 2010-10-7 17:08:13 | 显示全部楼层
本帖最后由 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[2])
Else
        MsgBox(0,"Error",@error)
EndIf


忘了说,wininet库有点旧了,需要对$AU3_UNICODE进行修改。
编译好的文件:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×

评分

参与人数 1金钱 +30 贡献 +2 收起 理由
afan + 30 + 2

查看全部评分

发表于 2010-10-7 17:44:00 | 显示全部楼层
回复 6# republican


    要修改什么地方么? 我这没修改也正常啊
 楼主| 发表于 2010-10-7 18:04:01 | 显示全部楼层
我也刚看到 WinINet 的东东,不过用http://www.autoitx.com/forum.php ... p;highlight=Wininet的附件的东西会报错:
+>18:02:05 Starting AutoIt3Wrapper v.2.0.1.24    Environment(Language:0804  Keyboard:00000804  OS: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[2] & "." & $AU3_VERSION[3]) >= 2.13 Or @AutoItUnicode
 楼主| 发表于 2010-10-7 18:11:50 | 显示全部楼层
我修改了WinINetConstants.au3的这行
Global Const $AU3_UNICODE = Number($AU3_VERSION[2] & "." & $AU3_VERSION[3]) >= 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
 楼主| 发表于 2010-10-7 18:20:15 | 显示全部楼层
回复 2# republican


谢谢,我已按照这种方式搞定。
发表于 2010-10-7 19:05:20 | 显示全部楼层
回复 7# afan

同8-9楼的问题。
发表于 2010-10-7 19:07:11 | 显示全部楼层
回复 11# republican


    那个不算问题吧,SciTE的报错也鸟它?
发表于 2010-10-7 19:14:00 | 显示全部楼层
回复 12# afan

@AutoItUnicode 本身就不存在,程序不可能运行的。

退出代码: [CODE]:2
发表于 2010-10-7 19:16:14 | 显示全部楼层
回复  afan

@AutoItUnicode 本身就不存在,程序不可能运行的。

退出代码: [CODE]:2
republican 发表于 2010-10-7 19:14



    直接运行 MsgBox(0, 0, @AutoItUnicode) 试试
发表于 2010-10-7 19:24:44 | 显示全部楼层
回复 14# afan

不好意思,刚才编译错文件了,所以才有此结论。

代码少的话,可以直接忽略sicte的报错。

但我不认为忽略sicte的错误报错对写一个“大型程序”有多大帮助,你仍然需要从错误中分辨哪些是正确的报错,哪些是不用管的,所以对于isdeclare类的报错我通常都遵循sicte,这样会省下很多无谓的思考。
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-12-23 04:42 , Processed in 0.097164 second(s), 29 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表