本帖最后由 happytc 于 2012-4-7 06:13 编辑
回复 happytc
可以试试我说的思路啊~ 先缩小指定区域(可以用_GDIPlus_GraphicsDrawImageRectRec ...
afan 发表于 2012-4-7 01:30
(可能就是昨晚想写个18楼的这个东西了,居然才睡几个小时就醒了,再也睡不着了)
算法的重要性在这里体现得太明显了(后来想了想,用StretchBlt函数肯定效率会下降些,所以没用)
下面的代码仅仅调用了很简单‘k-最近邻内插’算法来处理像素,速度马上就上去了。
等有空了,我再试一下高斯内插算法,看看效果是不是更好!
#include <GDIP.au3>
#include <GUIConstantsEx.au3>
#include <Memory.au3>
#include <String.au3>
Global $SocketID
;Opt('MustDeclareVars', 1)
_GDIPlus_Startup()
ImageMosaic()
_GDIPlus_Shutdown()
Func ImageMosaic()
Local $hGUI, $hImage, $hClone, $hGraphics, $hContext
Local $iColor, $iX, $iY, $iWidth, $iHeight, $sLink, $sPic
Local $iTestDotNum = 200, $fstretch = 10, $iInterMode = 5, $iSmoothMode = 7, $iOffsetMode = 4
$sLink = "myarticle.enet.com.cn"
$sPic = "/images/2007/0917/1189986155220/1.jpg"
If FileExists(@ScriptDir & "\Beauty.jpg") Then
$hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Beauty.jpg")
Else
ToolTip("Wait for downloading image...", @DesktopWidth / 2, @DesktopHeight /2, "Mosaic for image")
$hImage = _ImageFromNet($sLink, $sPic)
ToolTip("")
_GDIPlus_ImageSaveToFile($hImage, @ScriptDir & "\Beauty.jpg")
EndIf
$iWidth = _GDIPlus_ImageGetWidth($hImage)
$iHeight = _GDIPlus_ImageGetHeight($hImage)
$hGUI = GUICreate("Mosaic", $iWidth * 2, $iHeight)
GUISetState()
$hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
_GDIPlus_GraphicsDrawImage($hGraphics, $hImage, 0, 0)
$hClone = _GDIPlus_BitmapCloneArea($hImage, 0, 0, $iTestDotNum/$fstretch, $iTestDotNum/$fstretch)
$hContext = _GDIPlus_ImageGetGraphicsContext($hClone)
_GDIPlus_GraphicsSetInterpolationMode($hContext, $iInterMode)
_GDIPlus_GraphicsSetInterpolationMode($hGraphics, $iInterMode)
_GDIPlus_GraphicsSetPixelOffsetMode($hContext, $iOffsetMode)
_GDIPlus_GraphicsSetPixelOffsetMode($hGraphics, $iOffsetMode)
_GDIPlus_GraphicsSetSmoothingMode($hContext, $iSmoothMode)
_GDIPlus_GraphicsSetSmoothingMode($hGraphics, $iSmoothMode)
_GDIPlus_GraphicsDrawImage($hGraphics, $hImage, $iWidth, 0)
_GDIPlus_GraphicsDrawImageRectRect($hContext, $hImage, 0, 0, $iWidth, $iHeight, 0, 0, $iWidth/$fstretch, $iHeight/$fstretch)
_GDIPlus_GraphicsDrawImageRectRect($hGraphics, $hClone, 0, 0, $iWidth/$fstretch, $iHeight/$fstretch, $iWidth, 0, $iWidth, $iHeight)
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
_GDIPlus_ImageDispose($hImage)
_WinAPI_DeleteObject($hClone)
_GDIPlus_GraphicsDispose($hGraphics)
EndFunc ;==>ImageMosaic
Func _ImageFromNet($sHost, $sSource)
Local $sIp, $sData, $sSocket, $sRecvHeader = "", $sRecvBin = "0x", $aRet
Local $iBytes, $mBitmap, $iLength, $hData, $pData, $tMem, $aResult
TCPStartup()
$sIp = TCPNameToIP($sHost)
$sData = "GET " & $sSource & " HTTP/1.1" & @CRLF & "Host: " & $sHost & @CRLF & @CRLF
$sSocket = TCPConnect($sIp, 80)
TCPSend($sSocket, $sData)
If @error Then Return SetError(1, 1, 1)
Do
$sRecvHeader = TCPRecv($sSocket, 1)
Until $sRecvHeader <> ""
Do
$sRecvHeader &= TCPRecv($sSocket, 1)
Until StringInStr($sRecvHeader, @CRLF & @CRLF)
$aRet = _StringBetween($sRecvHeader, 'Content-Length: ', @CRLF)
If IsArray($aRet) Then
$iBytes = $aRet[0]
Do
$sRecvBin &= StringTrimLeft(TCPRecv($sSocket, 1024, 1), 2)
Until BinaryLen(Binary($sRecvBin)) >= $iBytes
TCPCloseSocket($sSocket)
TCPShutdown()
$mBitmap = Binary($sRecvBin)
$iLength = BinaryLen($mBitmap)
$hData = _MemGlobalAlloc($iLength, $GMEM_MOVEABLE)
$pData = _MemGlobalLock($hData)
$tMem = DllStructCreate("byte[" & $iLength & "]", $pData)
DllStructSetData($tMem, 1, $mBitmap)
_MemGlobalUnlock($hData)
$aResult = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", "hwnd", $pData, "int", True, "ptr*", 0)
If @error Then Return SetError(@error, @extended, 0)
$aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromStream", "ptr", $aResult[3], "int*", 0)
If @error Then Return SetError(@error, @extended, 0)
Return $aResult[2]
Else
TCPCloseSocket($SocketID)
TCPShutdown()
Return SetError(1, 1, 1)
EndIf
EndFunc ;==>_ImageFromNet
|