回 帖 发 新 帖 刷新版面

主题:怎样避免图像缩放时产生的锯齿

用drawimage画图,图像缩小时会产生锯齿,有没有办法避免啊?多谢。

回复列表 (共8个回复)

沙发

上个问题没有人回答。我只好把文字存成图片,在用drawimage按一定的比例画出来,但是锯齿比较严重。象T这样横平竖直的没事,可A那样有斜线的就不行了。
多谢。

板凳

是不是要用到矢量图啊?怎么做呢?郁闷。。。

3 楼

有同感。但不会做。
共同关注!

4 楼

Option Explicit

'说明:先调用LoadImage函数打开图片
'   再用ShowImage显示图片
'      最后不要忘记使用DisposeImage销毁内存中的图片。

Private Type GdiplusStartupInput
   GdiplusVersion As Long
   DebugEventCallback As Long
   SuppressBackgroundThread As Long
   SuppressExternalCodecs As Long
End Type

Private Enum GpStatus   'Status
   Ok = 0
   GenericError = 1
   InvalidParameter = 2
   OutOfMemory = 3
   ObjectBusy = 4
   InsufficientBuffer = 5
   NotImplemented = 6
   Win32Error = 7
   WrongState = 8
   Aborted = 9
   FileNotFound = 10
   ValueOverflow = 11
   AccessDenied = 12
   UnknownImageFormat = 13
   FontFamilyNotFound = 14
   FontStyleNotFound = 15
   NotTrueTypeFont = 16
   UnsupportedGdiplusVersion = 17
   GdiplusNotInitialized = 18
   PropertyNotFound = 19
   PropertyNotSupported = 20
End Enum

Private Declare Function GdiplusStartup Lib "gdiplus" (token As Long, inputbuf As GdiplusStartupInput, Optional ByVal outputbuf As Long = 0) As GpStatus
Private Declare Function GdiplusShutdown Lib "gdiplus" (ByVal token As Long) As GpStatus
Private Declare Function GdipDrawImage Lib "gdiplus" (ByVal graphics As Long, ByVal Image As Long, ByVal x As Single, ByVal y As Single) As GpStatus
Private Declare Function GdipDrawImageRect Lib "gdiplus" (ByVal graphics As Long, ByVal Image As Long, ByVal x As Single, ByVal y As Single, ByVal Width As Single, ByVal Height As Single) As GpStatus
Private Declare Function GdipCreateFromHDC Lib "gdiplus" (ByVal hdc As Long, graphics As Long) As GpStatus
Private Declare Function GdipDeleteGraphics Lib "gdiplus" (ByVal graphics As Long) As GpStatus
Private Declare Function GdipLoadImageFromFile Lib "gdiplus" (ByVal fileName As String, Image As Long) As GpStatus
Private Declare Function GdipDisposeImage Lib "gdiplus" (ByVal Image As Long) As GpStatus
Private Declare Function GdipGetImageWidth Lib "gdiplus" (ByVal Image As Long, Width As Long) As GpStatus
Private Declare Function GdipGetImageHeight Lib "gdiplus" (ByVal Image As Long, Height As Long) As GpStatus
Private Declare Function GdipDrawImageRectI Lib "gdiplus" (ByVal graphics As Long, ByVal Image As Long, ByVal x As Long, ByVal y As Long, ByVal Width As Long, ByVal Height As Long) As GpStatus

Private GDIP_Image As Long, GDIP_Token As Long, ImageFileName As String

Public Function LoadImage(ByVal ImagePath As String, Optional ByVal DelFile As Boolean = True) As Boolean
    Dim GpInput As GdiplusStartupInput, GDIP_Token As Long
    On Error Resume Next
    GpInput.GdiplusVersion = 1
    LoadImage = GdiplusStartup(GDIP_Token, GpInput) = 0
    If LoadImage Then
        '载入图片到内存中
        ImageFileName = IIf(DelFile, ImagePath, vbNullString)
        GdipLoadImageFromFile StrConv(ImagePath, vbUnicode), GDIP_Image
    End If
End Function

Public Sub DisposeImage()
  On Error Resume Next
  GdipDisposeImage GDIP_Image
  GdiplusShutdown GDIP_Token
  GDIP_Token = 0: GDIP_Image = 0
  'If Len(ImageFileName) Then Kill ImageFileName
End Sub

Public Sub GetImageWH(w As Long, h As Long)
    '获取图片原宽度和高度
    GdipGetImageWidth GDIP_Image, w
    GdipGetImageHeight GDIP_Image, h
End Sub

5 楼

'接上帖

'-------------缩略图函数-----------
Public Function ShowImage(ByVal hDC As Long, ByVal WMax As Long, ByVal HMax As Long, _
    Optional ByVal Top As Long = 0, Optional ByVal Left As Long = 0, _
    Optional ByRef ZoomP As Single = 0, Optional ByVal LSMode As Boolean = True) As Boolean

    'hDC为显示图片容器的hDC值   
    'WMax为最大宽度,HMax为最大高度,这段代码会根据最大宽度和高度调整图片大小。

    Dim w As Long, h As Long
    Dim gdip_Graphics As Long
    
    On Error Resume Next
    
    ShowImage = False
    
    If GdipCreateFromHDC(hdc, gdip_Graphics) Then
      DisposeImage
      Exit Function
    End If
    
    GetImageWH w, h
    
    If ZoomP <> 0 Then
        w = w * ZoomP
        h = h * ZoomP
    End If
    
    '智能调整图片大小和留空处理,根据最长边调整位置
    If (w > WMax) Or (h > HMax) Then
        If w > h Then
            ZoomP = CSng(WMax) / CSng(w)
            h = ZoomP * h
            w = WMax
            Top = (HMax - h) / 2 + Top
        Else
            ZoomP = CSng(HMax) / CSng(h)
            w = w * ZoomP
            h = HMax
            Left = (WMax - w) / 2 + Left
        End If
    ElseIf LSMode Then
        If w > h Then
            ZoomP = CSng(WMax) / CSng(w)
            h = ZoomP * h
            w = WMax
            Top = (HMax - h) / 2 + Top
        Else
            ZoomP = CSng(HMax) / CSng(h)
            w = w * ZoomP
            h = HMax
            Left = (WMax - w) / 2 + Left
        End If
    Else
        Top = (HMax - h) / 2 + Top
        Left = (WMax - w) / 2 + Left
    End If
  

    '使用GDI+直接从内存中缩略并绘图,GDI+有很好的抗锯齿能力
    ShowImage = GdipDrawImageRect(gdip_Graphics, GDIP_Image, Left, Top, w, h) = 0
    GdipDeleteGraphics gdip_Graphics
    ShowImage = True
End Function

'这段代码是我自己用的,感觉抗钜齿能力还算过得去。

6 楼

晕死,这个论坛最多只能发1000字以内的帖,只好分成两份发了。
把上面两个帖内容复制到一个模块中,按上面的说明调用三个函数就可以在一个容器上显示一幅图的缩图或是放大图了。

7 楼

非常感谢joforn。
由于我是初学者,有很多看不懂的地方,现在还在慢慢看。

8 楼

WORD和powerpoint中的艺术字可以任意拉伸,能不能在vb.net中画出word的艺术字啊?

我来回复

您尚未登录,请登录后再回复。点此登录或注册