republican 发表于 2010-5-31 11:39:20

请问如何基于DIB,DIBV5创建BMP图像? [已解决]

本帖最后由 republican 于 2010-8-10 09:07 编辑

做一回伸手党...

1. 假设我们通过屏幕截图讲数据读入剪切板

2. 通过_ClipBoard_GetData()函数我们可以获得DIB,DIBV5数据。

接下来我就不知道怎么做了,遂请教各位。

看了一下MS只有这么一个关于BMP的东西。

BMP.au3Func _BMPGetWidth(ByRef $BMPHandle)
      If IsArray($BMPHandle)=0 Then Return 0
      Return $BMPHandle
EndFunc

Func _BMPGetHeight(ByRef $BMPHandle)
      If IsArray($BMPHandle)=0 Then Return 0
      Return $BMPHandle
EndFunc

Func _BMPGetChecksum(ByRef $BMPHandle,$step=1)
      if not IsArray($BMPHandle) then Return -1
      $length=BinaryLen($BMPHandle)
      $a=1
      $b=0
      for $i=54 to $length
                $a=Mod($a+Dec(Hex(BinaryMid($BMPHandle,$i,1))),65521)
                $b=Mod($a+$b,65521)
      Next
      Return (BitShift(BitShift($b,-16),1)*2) + $a
EndFunc

Func _PixelFill(ByRef $BMPHandle,$x,$y,$color,$variation=0)
      Local $CheckChart
      Local $count=0
      $Tset=1
      Local $tracer[$Tset]
      $tracer[$tset-1]=$x&","&$y
      Local $CheckColor=Dec(_PixelRead($BMPHandle,$x,$y))
      $CheckChart[$y][$x]=1
      While 1
                if Abs(Dec(_PixelRead($BMPHandle,$x-1,$y))-$CheckColor)<=$variation Then
                        $CheckChart[$x-1][$y]=1
                        $count+=1
                        _PixelWrite($BMPHandle,$x-1,$y,$color)
                        $Tset+=1
                        ReDim $tracer[$Tset]
                        $tracer[$Tset-1]=$x&","&$y
                        $x=$x-1
                        ContinueLoop
                EndIf
                if Abs(Dec(_PixelRead($BMPHandle,$x,$y-1))-$CheckColor)<=$variation Then
                        $CheckChart[$x][$y-1]=1
                        $count+=1
                        _PixelWrite($BMPHandle,$x,$y-1,$color)
                        $Tset+=1
                        ReDim $tracer[$Tset]
                        $tracer[$Tset-1]=$x&","&$y
                        $y=$y-1
                        ContinueLoop
                EndIf
                if Abs(Dec(_PixelRead($BMPHandle,$x+1,$y))-$CheckColor)<=$variation Then
                        $CheckChart[$x+1][$y]=1
                        $count+=1
                        _PixelWrite($BMPHandle,$x+1,$y,$color)
                        $Tset+=1
                        ReDim $tracer[$Tset]
                        $tracer[$Tset-1]=$x&","&$y
                        $x=$x+1
                        ContinueLoop
                EndIf
                if Abs(Dec(_PixelRead($BMPHandle,$x,$y+1))-$CheckColor)<=$variation Then
                        $CheckChart[$x][$y+1]=1
                        $count+=1
                        _PixelWrite($BMPHandle,$x,$y+1,$color)
                        $Tset+=1
                        ReDim $tracer[$Tset]
                        $tracer[$Tset-1]=$x&","&$y
                        $y=$y+1
                        ContinueLoop
                EndIf
                $Point=StringSplit($tracer[$Tset-1],",")
                $x=$Point
                $y=$Point
                $Tset-=1
                ReDim $tracer[$Tset]
                if $tset=1 then ExitLoop
      Wend
      Return $count
EndFunc

func _RectangleWrite(ByRef $BMPHandle,$x,$y,$Width,$Height,$color,$Thickness=1)
      if $Thickness<1 then Return 0
      if $Thickness>1 then
                Return SubRectangleWrite($BMPHandle,$x,$y,$Width,$Height,$color,$Thickness)
      EndIf
      Local $TempW=Round($Width/2)
      Local $TempH=Round($Height/2)
      _LineWrite($BMPHandle,$x-$TempW,$y-$TempH,$x+$TempW,$y-$TempH,$color)
      _LineWrite($BMPHandle,$x+$TempW,$y-$TempH,$x+$TempW,$y+$TempH,$color)
      _LineWrite($BMPHandle,$x+$TempW,$y+$TempH,$x-$TempW,$y+$TempH,$color)
      _LineWrite($BMPHandle,$x-$tempw,$y+$TempH,$x-$TempW,$y-$TempH,$color)
      Return $Width*$Height
EndFunc

func SubRectangleWrite(ByRef $BMPHandle,$x,$y,$Width,$Height,$color,$Thickness)
      For $a=1 to $Thickness
                _RectangleWrite($BMPHandle,$x,$y,$Width-Round($a/2),$Height-Round($a/2),$color)
                _RectangleWrite($BMPHandle,$x,$y,$Width+Round($a/2),$Height+Round($a/2),$color)
      Next
      Return $Width*$Height
EndFunc

func _EllipseWrite(ByRef $BMPHandle,$X,$Y,$Width,$Height,$color,$Thickness=1)
      if $Thickness<1 then Return 0
      if $Thickness>1 then
                Return SubEllipseWrite($BMPHandle,$x,$y,$Width,$Height,$color,$Thickness)
      EndIf
      Local $SumA=$Width/2
      Local $SumB=$Height/2
      Local $LastY=0
      Local $temp,$test,$h
      _PixelWrite($BMPHandle,Floor($x-$Width/2),$y,$color)
      _PixelWrite($BMPHandle,$x+$Width/2,$y,$color)
      For $a=-$Width/2 to $Width/2
                $temp=Sqrt(($SumB^2)*(1-(($a^2)/($SumA^2))))
                if $temp>$LastY then
                        $test=$temp-$LastY
                Else
                        $test=$LastY-$temp
                EndIf
                If $test<=1 then
                        _PixelWrite($BMPHandle,$x+$a,$y+$temp,$color)
                        _PixelWrite($BMPHandle,$x+$a,$y-$temp,$color)
                Else
                        _LineWrite($BMPHandle,$x+$a-1,$y+$LastY,$x+$a,$y+$temp,$color)
                        _LineWrite($BMPHandle,$x+$a-1,$y-$LastY,$x+$a,$y-$temp,$color)
                EndIf
                $LastY=$temp
      Next
      $h=(($sumA-$SumB)^2)/(($sumA+$SumB)^2)
      Return 3.14159*($SumA+$SumB)*(1+((3*$h)/(10+Sqrt(4-(3*$h)))))
EndFunc

Func SubEllipseWrite(ByRef $BMPHandle,$x,$y,$Width,$Height,$color,$Thickness)
      for $a=1 to $Thickness
                _EllipseWrite($BMPHandle,$x,$y,$Width+$a,$Height+$a,$color)
                Local $Return=_EllipseWrite($BMPHandle,$x,$y,$Width-$a,$Height-$a,$color)
      Next
      Return $Return
EndFunc

Func SubLineWrite(ByRef $BMPHandle,$x1,$y1,$x2,$y2,$color,$loops)
      if $loops<1 then Return 0
      for $a=1 to $loops-1
                Local $Return=_LineWrite($BMPHandle,$x1+$a,$y1,$x2+$a,$y2,$color)
                _LineWrite($BMPHandle,$x1-$a,$y1,$x2-$a,$y2,$color)
      Next
      Return $Return
EndFunc

Func _LineWrite(ByRef $BMPHandle,$x1,$y1,$x2,$y2,$color,$Thickness=1)
      If $Thickness<>1 then
                Local $Return=SubLineWrite($BMPHandle,$x1,$y1,$x2,$y2,$color,$Thickness)
                Return $Return
      EndIf
      If $x1=$x2 or $y1=$y2 Then
                if $x1=$x2 and $y1=$y2 then
                        _PixelWrite($BMPHandle,$x1,$y1,$color)
                        Return 1
                EndIf
                if $x1=$x2 then
                        if $y1>$y2 Then
                              Local $hold=$y1
                              $y1=$y2
                              $y2=$hold
                        EndIf
                        For $a=$y1 to $y2
                              _PixelWrite($BMPHandle,$x1,$a,$color)
                        Next
                        Return $y2-$y1
                EndIf
                if $y1=$y2 Then
                        If $x1>$x2 Then
                              Local $hold=$x2
                              $x2=$x1
                              $x1=$hold
                        EndIf
                        for $a=$x1 to $x2
                              _PixelWrite($BMPHandle,$a,$y1,$color)
                        Next
                        Return $x2-$x1
                EndIf
      EndIf
      If $x1>$x2 Then
                Local $hold=$x2
                $x2=$x1
                $x1=$hold
                $hold=$y1
                $y1=$y2
                $y2=$hold
      EndIf
      Local $slope=($y2-$y1)/($x2-$x1)
      if $y2>$y1 Then
                Local $highy=$y2
                Local $lowy=$y1
      Else
                Local $highy=$y1
                Local $lowy=$y2
      EndIf
      If $x2-$x1>$highy-$lowy Then
                Local $stepx=1
                Local $stepy=$slope
      Else
                Local $stepx=1/abs($slope)
                if $y1>$y2 then
                        Local $stepy=-1
                Else
                        Local $stepy=1
                EndIf
      EndIf
      Local $count=0
      for $a=$x1 to $x2 step $stepx
                _PixelWrite($BMPHandle,$a,$y1+($stepy*$count),$color)
                $count+=1
      Next
      Return Sqrt(($highy-$lowy)*($highy-$lowy)+($x2-$x1)*($x2-$x1))
EndFunc

Func _BMPCreate ($Width,$Height)
      Local $c=Mod($Width,4)
      Local $d=Binary("")
      if $c=3 then $d=Binary("0x000000")
      if $c=2 then $d=Binary("0x0000")
      if $c=1 then $d=Binary("0x00")      
                                                                                                                ;***BMP header (54bytes total)***
      Local $Header=Binary("0x424D"& _                                    ;2bytes, BM signature
                                                "00000000"& _                                        ;4bytes, filesize (optional, omitted)
                                                "0000"& _                                                ;2bytes, reserved
                                                "0000"& _                                                ;2bytes, reserved
                                                "36000000"& _                                        ;4bytes, offset to image data
                                                "28000000"& _                                        ;4bytes, BITMAPINFOHEADER
                                                _Reverse8(Hex($Width,8))& _                ;4bytes, bitmap width
                                                _Reverse8(Hex($Height,8))& _      ;4bytes, bitmap hieght
                                                "0100"& _                                                ;2bytes, bitmap planes
                                                "1800"& _                                                ;2bytes, bitmap bitdepth
                                                "00000000"& _                                        ;4bytes, bitmap compression type (none)
                                                _Reverse8(Hex(($Height)* _
                                                ($Width)*3+($Height*$c),8))& _      ;4bytes, bitmap data size
                                                "00000000"& _                                        ;4bytes, bitmap horizontal resolution (optional,omitted)
                                                "00000000"& _                                        ;4bytes, bitmap vertical resolution (optional,omitted)
                                                "00000000"& _                                        ;4bytes, bitmap colors (optional?, omitted)
                                                "00000000")                                                ;4bytes, important colors (optional?, omitted)
                                                                                                                ;***End Header***
      Local $rowData=Binary("")
      Local $imageData=Binary("")
      for $n=1 to $Width
                $rowData&=Binary("0xFFFFFF")
      Next
      $rowData&=$d
      for $m=1 to $Height
                $imageData&=$rowData
      Next      
      Local $BMPHandle
      $BMPHandle=$c
      $BMPHandle=$Width
      $BMPHandle=$Height
      $BMPHandle=$Header&$imageData
      Return $BMPHandle
EndFunc

Func _BMPOpen($Path,$Progress=1)
      Local $Bpath=FileOpen($Path,16)
      If $Bpath=-1 then Return -1
      $AllOf=FileRead($Bpath)
      If BinaryMid($AllOf,1,2)<>"0x424D" then Return -2
      $x=Dec(_Reverse8(Hex(BinaryMid($AllOf,19,4))))
      $y=Dec(_Reverse8(Hex(BinaryMid($AllOf,23,4))))
      if $x=0 or $y=0 then Return -3
      for $c=$x to 0 step -4
                if $c<4 then ExitLoop
      Next
      Local $BMPHandle
      $BMPHandle=$c
      $BMPHandle=$x
      $BMPHandle=$y
      $BMPHandle=$AllOf
      return $BMPHandle
EndFunc

Func _PixelRead(ByRef $BMPHandle,$x,$y)
      If IsArray($BMPHandle)=False or $x>$BMPHandle-1 Or $x<0 Or $y>$BMPHandle-1 Or $y<0 Then Return 0
      $color = Hex(BinaryMid($BMPHandle,_ChordToOffset($x,$y,$BMPHandle),3))
      $color = _Reverse6($Color)
      Return $Color
EndFunc      

Func _PixelWrite(ByRef $BMPHandle,$x,$y,$color)
      If $x>$BMPHandle-1 Or $x<0 Or $y>$BMPHandle-1 Or $y<0 or StringLen($color)<>6 or Dec($Color)=0 Then Return 0
      $color = _Reverse6($Color)
      $BMPHandle=BinaryMid($BMPHandle,1,_ChordToOffset($x,$y,$BMPHandle))&Binary("0x"&$color)&BinaryMid($BMPHandle,_ChordToOffset($x,$y,$BMPHandle)+4)
      Return 1
EndFunc

Func _ChordToOffset($x,$y,ByRef $BMPHandle)
                Local $row=($BMPHandle*3+$BMPHandle)
                return 54+(($BMPHandle*$row)-(($y+1)*$row)+($x*3))
      EndFunc
      
Func _BMPWrite(ByRef $BMPHandle,$Fpath,$Progress=1)
      if IsArray($BMPHandle)=False then Return 0
      $out=FileOpen($Fpath,18)
      if $out=-1 then return -1
      FileWrite($out,$BMPHandle)
      FileClose($out)
      Return 1
EndFunc

Func _Reverse8($inHex)
      Return StringMid($inHex,7,2)&StringMid($inHex,5,2)&StringMid($inHex,3,2)&StringMid($inHex,1,2)
EndFunc

Func _Reverse6($inHex)
      Return StringMid($inHex,5,2)&StringMid($inHex,3,2)&StringMid($inHex,1,2)
EndFunc
页: [1]
查看完整版本: 请问如何基于DIB,DIBV5创建BMP图像? [已解决]