首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VB >

搞了三个月,搞不定,API的文字镜面翻转有关问题

2012-12-14 
搞了三个月,搞不定,API的文字镜面翻转问题背景是GradientFill填充的一个渐变然后DrawText一个文本到中间现

搞了三个月,搞不定,API的文字镜面翻转问题
背景是GradientFill填充的一个渐变
然后DrawText一个文本到中间

现在希望在文本下实现翻转特效,不是旋转,是水平或者垂直翻转,就好象水中的倒影
这个难道用GDI不能实现吗?

[最优解释]


Option Explicit
Private Declare Function BeginPath Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function EndPath Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function TextOut Lib "gdi32" Alias "TextOutA" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal lpString As String, ByVal nCount As Long) As Long
Private Declare Function GetPath Lib "gdi32" (ByVal hdc As Long, lpPoint As POINTAPI, lpTypes As Byte, ByVal nSize As Long) As Long
Private Declare Function CreatePolyPolygonRgn Lib "gdi32" (lpPoint As POINTAPI, lpPolyCounts As Long, ByVal nCount As Long, ByVal nPolyFillMode As Long) As Long
Private Declare Function FillRgn Lib "gdi32" (ByVal hdc As Long, ByVal hRgn As Long, ByVal hBrush As Long) As Long
Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function SelectClipRgn Lib "gdi32" (ByVal hdc As Long, ByVal hRgn As Long) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function GetStockObject Lib "gdi32" (ByVal nIndex As Long) As Long
Private Declare Function FlattenPath Lib "gdi32" (ByVal hdc As Long) As Long

Private Const PT_MOVETO = &H6
Private Const PT_LINETO = &H2
Private Const PT_CLOSEFIGURE = &H1
Private Const PT_BEZIERTO = &H4

Private Const BLACK_BRUSH = 4
Private Declare Function GetRgnBox Lib "gdi32" (ByVal hRgn As Long, lpRect As RECT) As Long
Private Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
End Type

Private Const WINDING = 2
Private Const ALTERNATE = 1

Private Type POINTAPI
        x As Long
        y As Long
End Type

Private Sub Command1_Click()
Me.FontSize = 48
Dim hdc As Long
hdc = GetDC(Me.hwnd)
BeginPath hdc
TextOut hdc, 50, 100, "山", 2    '为简单起见,用独体字作为例子,这样得到的路径只有一个多边形
EndPath hdc
TextOut hdc, 50, 100, "山", 2


FlattenPath hdc    '为简单起见,把路径关键点强制转换为起点、终点类型,除二者之外,可能还有贝塞尔控制点等等

Dim nSz As Long
Dim pts() As POINTAPI, types() As Byte
ReDim pts(0), types(0)
nSz = GetPath(hdc, pts(0), types(0), 0)    '获取路径关键点个数
ReDim pts(nSz - 1), types(nSz - 1)
GetPath hdc, pts(0), types(0), nSz    'pts存放坐标,types存放点类型,即起点6,终点2,封闭点3,一个字可能有多个多边形构成,也就有多个起点
Dim i As Long
For i = 0 To nSz - 1
    pts(i).y = 320 - pts(i).y        '变换坐标,这里是反转纵坐标,相当于垂直镜像
Next
Dim hRgn As Long
Dim nCounts(0 To 0) As Long
'nCounts为路径中每个多边形的点数数组,实际使用你需要自己计算数组大小和每个多边形的点数,可通过types进行
nCounts(0) = nSz
hRgn = CreatePolyPolygonRgn(pts(0), nCounts(0), 1, WINDING)   '创建多边形区域

FillRgn hdc, hRgn, GetStockObject(BLACK_BRUSH)    '填充区域,把变换后的字显示出来
DeleteObject hRgn
ReleaseDC Me.hwnd, hdc
End Sub



[其他解释]
不就看背面吗有什么难的。
'窗体上放1个命令按钮Command1,2个图片框Picture1,Picture2
Option Explicit
Private Declare Function GetPixel Lib "gdi32 " (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
Private Declare Function SetPixel Lib "gdi32 " (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long) As Long

Private Sub Command1_Click()
        With Picture1
                .AutoRedraw = True
                .ScaleMode = vbPixels
                .FontSize = 30
                .ForeColor = &HFF
                .CurrentX = .ScaleWidth / 4
                .CurrentY = .ScaleHeight / 4
        End With
        Picture1.Print "不就看背面吗有什么难的 "
        Picture1.Refresh
        Dim x As Integer, y As Integer
        Dim w As Integer, h As Integer
        Dim c As Long
        Dim h1 As Long, h2 As Long
        w = Picture1.ScaleWidth
        h = Picture1.ScaleHeight
        Picture2.ScaleMode = vbPixels
        Picture2.AutoRedraw = True
        h1 = Picture1.hdc


        h2 = Picture2.hdc
        For x = 0 To w
                For y = 0 To h
                        c = GetPixel(h1, x, y)
                        SetPixel h2, w - x, y, c
                        DoEvents
                Next y
        Next x
        Picture2.Refresh
End Sub

Private Sub Form_Load()
    Picture1.AutoRedraw = False
    Picture2.AutoRedraw = False
End Sub


[其他解释]
用 StretchBlt
参数中源和目标的高度或宽度互为负数,就是翻转效果。
[其他解释]
http://topic.csdn.net/t/20051222/14/4475066.html
[其他解释]
引用:
用 StretchBlt
参数中源和目标的高度或宽度互为负数,就是翻转效果。

牛B
学到一招
[其他解释]
picture1显示源图,picture2显示翻转后的图片,用下面的代码就可以实现镜像:
'左右翻转
Picture2.PaintPicture Picture1.Picture, Picture1.Width, 0, -Picture1.Width, Picture1.Height
'上下翻转
Picture2.PaintPicture Picture1.Picture, 0, Picture1.Height, Picture1.Width, -Picture1.Height
取点的办法比较麻烦,用Picture1.Point(x,y)获取该点的颜色值,并用Pircture2.PSet(x,y),nColor画点,nColor就是先前获取的点的颜色值。将获取的点保存到二维数组,翻转的原理就是按不同的顺序读取数组并显示。比如左右翻转就是按逆序读取横向的数据,纵向按原来顺序读取。
[其他解释]
PaintPicture 其实和 StretchBlt 是一样的原理(说不定就是封装)。
看楼主是用 API 绘图,不一定已经输出到 PictureBox 上,所以推荐 StretchBlt。
[其他解释]
引用:
PaintPicture 其实和 StretchBlt 是一样的原理(说不定就是封装)。
看楼主是用 API 绘图,不一定已经输出到 PictureBox 上,所以推荐 StretchBlt。

应该是封装了的,所以我从不用PaintPicture,直接用StretchBlt。

[其他解释]
我先试试
你们等我
[其他解释]
引用:
引用:
用 StretchBlt
参数中源和目标的高度或宽度互为负数,就是翻转效果。

牛B
学到一招


学了一招
[其他解释]
不会操作,似乎不行
因为有背景的
用的是StretchBit
但是不知道怎么处理
背景是渐变的

[其他解释]
谁能提供下例子
哭死了

[其他解释]
CREATE hFont

TempDC=CreateCompatibleDC()

SelectObject(TempDC,hFont)

DrawText(TempDC,....)


CurrentDC=GetDC()

StretchBit(CurrentDC,....,TempDC....,SRCCOPY)

ReleaseDC(CurrentDC)
DeleteDC(TempDC)
DeleteObject(hFont)

结果在StretchBit这句直接报错,界面出现一个Error的MsgBox

[其他解释]
给个思路,伪码:


BeginPath  '开启路径
TextOut    '输出文字
EndPath    '结束路径
GetPath    '获取路径(文字的轮廓,关键点坐标数组)
...        '做你想做的变换(坐标变换而已,想干嘛都行)
CreatePolyPolygonRgn   '根据变换后的文字轮廓创建区域
FillRgn    '填充变换后文字区域

即先把文字变为矢量图,再进行变换.

要求不高的话,可StretchBit翻转后,再透明贴图TRANSPARENTBLT

[其他解释]
引用:
不会操作,似乎不行
因为有背景的
用的是StretchBit
但是不知道怎么处理
背景是渐变的

图形处理的基本做法,用掩码,只输出需要的部分。
需要翻转时,文字和掩码一起翻转再输出。
具体函数自己查。
[其他解释]
引用:
谁能提供下例子
哭死了

我2楼那个不行?我测试成功了的.
[其他解释]
我今晚不睡再试试
你们再等我下下
同时回复楼上的
真的不行

[其他解释]
还是不行
现在用的是路径的方法,
首先是
BeginPath()
DrawText()
EndPath()
PathToRgn()
GetRgnData()
ExtCreateRgn()就不懂了
我不知道如何把ExtCreateRgn()产生的区域合并到当前上去
14楼的,你能提供个例子吗?
[其他解释]
楼上的
谢谢
我再试试
[其他解释]
想到非常简单的方法:
1)用 StretchBlt 将背景翻转
2)用 DrawText 输出正常的文字
3)在用 StretchBlt 将背景+文字翻转
不就得到文字翻转的效果了!


[其他解释]
连续两晚都3,4点了
希望这次真能解决
[其他解释]
呵呵,好玩。
依楼上前辈想法制作的结果...

'以下需要1个From,在From中置入1个PictureBox,并於PictureBox中加入背景图形
Option Explicit '所有变数必需宣告
Private Declare Function StretchBlt Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long '镜像/伸拉图形
Private Declare Function DrawText Lib "user32" Alias "DrawTextA" (ByVal hdc As Long, ByVal lpStr As String, ByVal nCount As Long, lpRect As RECT, ByVal wFormat As Long) As Long '绘制字串
Private Const DT_SINGLELINE As Long = &H20 '仅绘制单行
Private Const DT_CALCRECT As Long = &H400  '取得字串范围

Private Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
End Type

Private Sub Form_Load()


  drawMirrorText Picture1, "ABCdefg" '镜像绘制字串(目的PictureBox,字串)
End Sub

Private Function drawMirrorText(mPic As PictureBox, mStr As String) '镜像绘制字串(目的PictureBox,字串)
  Dim mRC As RECT
  DrawText mPic.hdc, mStr, -1, mRC, DT_CALCRECT '取得字串宽高
  mRC.Left = (mPic.ScaleWidth - mRC.Right) / 2  '左右居中
  mRC.Right = mRC.Left + mRC.Right
  mRC.Top = (mPic.ScaleHeight - (mRC.Bottom * 2)) / 2 '上下居中(共2行高)
  mRC.Bottom = mRC.Top + mRC.Bottom
  
  StretchBlt mPic.hdc, 0, mPic.ScaleHeight - 1, mPic.ScaleWidth, -mPic.ScaleHeight, mPic.hdc, 0, 0, mPic.ScaleWidth, mPic.ScaleHeight, vbSrcCopy '上下翻转原图形
  DrawText mPic.hdc, mStr, -1, mRC, DT_SINGLELINE '绘制镜像字串
  StretchBlt mPic.hdc, 0, mPic.ScaleHeight - 1, mPic.ScaleWidth, -mPic.ScaleHeight, mPic.hdc, 0, 0, mPic.ScaleWidth, mPic.ScaleHeight, vbSrcCopy '再次上下翻转图形回正向
  DrawText mPic.hdc, mStr, -1, mRC, DT_SINGLELINE '绘制正向字串
  mPic.Refresh
End Function

[其他解释]
感谢各位了
最近出差
结贴

热点排行