Skip to content

Instantly share code, notes, and snippets.

@KOZ60
Created November 10, 2023 20:07
Show Gist options
  • Save KOZ60/d7b6775416d20a1a3bc1c3f599e6cc6b to your computer and use it in GitHub Desktop.
Save KOZ60/d7b6775416d20a1a3bc1c3f599e6cc6b to your computer and use it in GitHub Desktop.
GraphicsWrapper

ビットマップから Graphics.FromImage で Grapchis オブジェクトを作成し、TextRenderer で描画すると太く見えますが、 太く見えるのはハーフトーンで描画される部分が真っ黒に塗りつぶされているためだったみたいです。 ハーフトーンの品質を上げるとキレイに見えます。

こんなクラスを作って

Imports System.Drawing
Imports System.Drawing.Text
Imports System.Runtime.InteropServices

Public Class GraphicsWrapper
    Implements IDisposable

    <DllImportAttribute("gdi32.dll")>
    Private Shared Function SelectPalette(hdc As IntPtr,
     htPalette As IntPtr, bForceBackground As Boolean) As IntPtr
    End Function

    <DllImportAttribute("gdi32.dll")>
    Private Shared Function RealizePalette(hdc As IntPtr) As Integer
    End Function

    Private ReadOnly tmpGraphics As Graphics
    Private ReadOnly hdc As IntPtr
    Private ReadOnly oldPal As IntPtr
    Private ReadOnly mainGraphics As Graphics

    Public ReadOnly Property Graphics As Graphics
        Get
            Return mainGraphics
        End Get
    End Property

    Public Sub New(img As Image, useHalftone As Boolean)
        If useHalftone Then
            tmpGraphics = Graphics.FromImage(img)
            hdc = tmpGraphics.GetHdc()
            oldPal = SetUpPalette(hdc, False, True)
            mainGraphics = Graphics.FromHdc(hdc)
        Else
            mainGraphics = Graphics.FromImage(img)
        End If
        mainGraphics.TextRenderingHint = TextRenderingHint.AntiAlias
    End Sub

    Shared Function SetUpPalette(dc As IntPtr, force As Boolean, rp As Boolean) As IntPtr
        Dim halftonePalette = Graphics.GetHalftonePalette()
        Dim result = SelectPalette(dc, halftonePalette, force)
        If rp Then
            RealizePalette(dc)
        End If
        Return result
    End Function

    Private disposedValue As Boolean

    Protected Overridable Sub Dispose(disposing As Boolean)
        If Not disposedValue Then
            disposedValue = True
            mainGraphics.Dispose()
            If tmpGraphics IsNot Nothing Then
                If oldPal <> IntPtr.Zero Then
                    SelectPalette(hdc, oldPal, False)
                End If
                tmpGraphics.ReleaseHdc(hdc)
                tmpGraphics.Dispose()
            End If
        End If
    End Sub

    Public Sub Dispose() Implements IDisposable.Dispose
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub
End Class

次のように描画します。

Dim str = "葛󠄀城市"
Using addFnt As New Font("メイリオ", 7.5, FontStyle.Regular, GraphicsUnit.Millimeter),
       br = New SolidBrush(Color.Black)
    Using img As New Bitmap(256, 256)
        Using wrapper = New GraphicsWrapper(img, True)
            wrapper.Graphics.Clear(Color.White)
            TextRenderer.DrawText(wrapper.Graphics, str, addFnt, New Point(0, 0), Color.Black)
        End Using
        Using wrapper = New GraphicsWrapper(img, False)
            TextRenderer.DrawText(wrapper.Graphics, str, addFnt, New Point(0, 32), Color.Black)
        End Using
        Using wrapper = New GraphicsWrapper(img, True)
            wrapper.Graphics.DrawString(str, addFnt, br, New PointF(0, 64))
        End Using
        Using wrapper = New GraphicsWrapper(img, False)
            wrapper.Graphics.DrawString(str, addFnt, br, New PointF(0, 96))
        End Using
        img.Save("z:\temp.bmp")
    End Using
End Using

結果は

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment