MakeGif.vb
'' 
'' このコードは、DioDocs for Imaging のサンプルの一部として提供されています。
'' © MESCIUS inc. All rights reserved.
'' 
Imports System.IO
Imports System.Drawing
Imports System.Collections.Generic
Imports System.Linq
Imports System.Numerics
Imports GrapeCity.Documents.Drawing
Imports GrapeCity.Documents.Text
Imports GrapeCity.Documents.Imaging

'' このサンプルは、金魚の画像(BmpTransforms で使用されているものと同一)を読み込み、
'' さまざまな変換を適用して複数のフレームを作成し、
'' それらを組み合わせてアニメーション GIF を生成します。
Public Class MakeGif
    Function GenerateImageStream(
                ByVal targetMime As String,
                ByVal pixelSize As Size,
                ByVal dpi As Single,
                ByVal opaque As Boolean,
                Optional sampleParams As String() = Nothing) As Stream

        If Not targetMime = MimeTypes.GIF Then
            Throw New Exception("This sample only supports GIF output format.")
        End If

        '' GIFのサイズを適切な範囲に抑えます。
        Dim side2 = Math.Min(400, Math.Min(pixelSize.Width, pixelSize.Height))

        '' 単一の画像を反転・回転させて、ターゲットGIF用のフレームを用意します。
        Dim move1() As GcBitmap = New GcBitmap(2) {}
        Dim move2() As GcBitmap = New GcBitmap(3) {}
        Using bmpSrc = New GcBitmap(Path.Combine("Resources", "Stock", "goldfish.jpg"))
            bmpSrc.Opaque = opaque
            '' 魚の頭が動かないように調整しながら、通常の画像と反転させた画像を作成します。
            Using tbmp = bmpSrc.Resize(side2, side2)
                move1(0) = New GcBitmap(tbmp.PixelWidth, tbmp.PixelHeight, tbmp.Opaque, tbmp.DpiX, tbmp.DpiY)
                move1(0).Clear(Color.White)
                move1(0).BitBlt(tbmp, -CType(side2 / 14.0F, Integer), 0)
            End Using
            Using tbmp = move1(0).FlipRotate(FlipRotateAction.FlipHorizontal)
                move1(1) = New GcBitmap(tbmp.PixelWidth, tbmp.PixelHeight, tbmp.Opaque, tbmp.DpiX, tbmp.DpiY)
                move1(1).Clear(Color.White)
                move1(1).BitBlt(tbmp, -CType(side2 / 14.0F, Integer), 0)
                move1(1).BitBlt(tbmp, 0, 0)
            End Using
            move2(0) = move1(0).FlipRotate(FlipRotateAction.Rotate90)
            move2(1) = move1(0).FlipRotate(FlipRotateAction.Rotate180)
            move2(2) = move1(0).FlipRotate(FlipRotateAction.Rotate270)
        End Using
        '' 動きを組み合わせます。
        Dim bmps = New List(Of GcBitmap)()
        For i = 0 To 3
            bmps.Add(move1(0))
            bmps.Add(move1(1))
        Next
        bmps.Add(move1(0))
        For i = 0 To 2
            bmps.Add(move1(0))
            bmps.Add(move2(0))
            bmps.Add(move2(1))
            bmps.Add(move2(2))
        Next
        bmps.Add(move1(0))
        '' GIFを作成します。
        Dim ms = New MemoryStream()
        Using gw = New GcGifWriter(ms)
            gw.LogicalScreenWidth = bmps(0).PixelWidth
            gw.LogicalScreenHeight = bmps(0).PixelHeight
            gw.PixelAspectRatio = 1
            gw.AllowAddingTransparentColor = False

            For Each bmp In bmps
                gw.AppendFrame(bmp, 255, 0, 0, GifDisposalMethod.DoNotDispose, 16)
            Next
        End Using
        '' GIFフレームの作成に使用したビットマップを破棄します。
        For Each bmp In bmps.Distinct()
            bmp.Dispose()
        Next

        ms.Seek(0, SeekOrigin.Begin)
        Return ms
    End Function

    Public ReadOnly Property DefaultMime() As String
        Get
            Return MimeTypes.GIF
        End Get
    End Property
End Class