找回密码
 加入
搜索
查看: 11124|回复: 20

[图形处理] 如何对图片局部选择区域高亮和打上马赛克?

 火.. [复制链接]
发表于 2012-4-1 09:07:44 | 显示全部楼层 |阅读模式
本帖最后由 jorlon 于 2012-4-1 09:09 编辑

就是先用鼠标在图片上拉选一个框,并对这个框内的图形打马赛克?或对这个框内图形高亮显示(当然先对整个图片的亮度调低),最好还能对框边缘作模糊化处理,让边框看起来不那么明显
发表于 2012-4-1 09:17:11 | 显示全部楼层
传说中的薄码
发表于 2012-4-1 10:53:59 | 显示全部楼层
喜欢步兵不喜欢骑兵的说,干嘛要上马?要藏着掖着的话就用画板涂涂就行了
发表于 2012-4-1 16:19:27 | 显示全部楼层
这个。可以用处不大吧
发表于 2012-4-2 01:34:40 | 显示全部楼层
本帖最后由 happytc 于 2012-4-2 03:11 编辑

回复 1# jorlon


    打马赛克原理很简单,就是定义个像素区块,如3X3的,然后把这个区块内的所有像素色彩都用这个区块的某一个像素色彩代替,如区块里第一个像素/中间像素/随机一个/或平均值都可以。难的是如何优化算法。若没有好的算法,一个大图,要花费很长时间来做这个东西。

若想增加速度,可以用_GDIPlus_BitmapLockBits()函数把位图锁进内存再操作,但又有指针有时操作错误(不安全)的可能。若直接用_GDIPlus_BitmapGetPixel()函数和_GDIPlus_BitmapSetetPixel()来做,效率明显不高。
下面给个后一种方法的打马赛克的。(看看美女的嘴打到了)

#Include <GDIP.au3>
#Include <GUIConstantsEx.au3>
#Include <ScreenCapture.au3>
#include <Memory.au3>
#include <String.au3>

Global $SocketID
Opt('MustDeclareVars', 1)
_GDIPlus_Startup()
ImageMosaic()
_GDIPlus_Shutdown()

Func ImageMosaic()
        Local $hGUI, $hImage, $hBmp, $hGraphics
        Local $iColor, $iX, $iY, $iWidth, $iHeight, $sLink, $sPic, $iXnum, $iYnum
        
        $sLink = "myarticle.enet.com.cn"
        $sPic = "/images/2007/0917/1189986155220/1.jpg"
        $hImage = _ImageFromNet($sLink, $sPic)
        $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)
        
        $iXnum = Int($iWidth / 2)
        $iYnum = Int($iHeight / 2)

        For $iX = $iXnum - 50 To $iXnum + 50 Step 10
                For $iY = $iYnum - 50 To $iYnum + 50 Step 10
                        $iColor = _GDIPlus_BitmapGetPixel($hImage, $iX + 1, $iY + 1)
                        For $i = 0 To 10
                                For $j = 0 To 10
                                        _GDIPlus_BitmapSetPixel($hImage, $iX + $i, $iY + $j, $iColor)
                                Next
                        Next
                        
                Next
        Next
        
        _GDIPlus_GraphicsDrawImage($hGraphics, $hImage, $iWidth, 0)

        Do
        Until GUIGetMsg() = $GUI_EVENT_CLOSE

        _GDIPlus_ImageDispose($hImage)
        _WinAPI_DeleteObject($hBmp)
        _GDIPlus_GraphicsDispose($hGraphics)
EndFunc
 

 
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
 

本帖子中包含更多资源

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

×

评分

参与人数 3威望 +5 金钱 +50 贡献 +20 收起 理由
楼上风云 + 10 对GDI和API学习有帮助
pusofalse + 5 + 20 + 10 学习了。
afan + 30

查看全部评分

发表于 2012-4-2 04:51:51 | 显示全部楼层
本帖最后由 qq342252004 于 2012-4-2 08:32 编辑

支持一下,性感部位打格仔。
发表于 2012-4-2 06:52:11 | 显示全部楼层
如果支持鼠标拖动到某个控件到“打马赛马部位”,就更方便了!(代码没看)
PS:还是喜欢无码的
发表于 2012-4-2 09:25:31 | 显示全部楼层
回复 5# happytc


     找不到GDIP.au3
发表于 2012-4-2 10:11:44 | 显示全部楼层
回复 5# happytc

发全身照,打重点部位  
发表于 2012-4-2 12:16:16 | 显示全部楼层
回复 9# leon460


哈哈,赞同
发表于 2012-4-2 13:02:49 | 显示全部楼层
我是看到图片后才来的。
发表于 2012-4-2 13:24:49 | 显示全部楼层
支持无码,抗议有码,
发表于 2012-4-2 13:28:41 | 显示全部楼层
如果支持鼠标拖动到某个控件到“打马赛马部位”,就更方便了!(代码没看)
PS:还是喜欢无码的{:face (303 ...
pp648852 发表于 2012-4-2 06:52


用鼠标拖拉,加上这个很容易呀

上面只是个示例代码
发表于 2012-4-6 09:51:39 | 显示全部楼层
回复 5# happytc
这女人最柔弱的地方,被楼主给。。。了。
强。
发表于 2012-4-6 11:55:18 | 显示全部楼层
本帖最后由 afan 于 2012-4-6 14:57 编辑

先缩小指定区域,再 _WinAPI_StretchBlt() 放大至指定区域,效率比区域内逐个像素去覆写至少快 200 倍(区域越大、格子数量越大,则效率悬殊越大)。
思路给了,有兴趣的可以自己测试。

评分

参与人数 1金钱 +50 收起 理由
pusofalse + 50 Nice~

查看全部评分

您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-5-7 03:31 , Processed in 0.085838 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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