SSブログ

[.NET]メールの送信(.NET2.0以降) [Programming .NET Tips]

[ポイント]
メールを送信するサンプルプログラムです。(最も簡単な例)
クラスライブラリ
 .NETFramework2.0から新たに追加されたクラスを使用しています。
 (1.1以前では『System.Web.Mail』名前空間のクラスが使用されていましたが、
  2.0以降は『System.Net.Mail』名前空間のクラスが推奨されています。)
クラス名/列挙体名概要
System.Net.Mail.SmtpClientクラスSMTPサーバを表すクラスです。
System.Net.Mail.MailMessageクラスメールを表すクラスです。
System.Net.Mail.MailAddressクラスメールアドレスを表すクラスです。
System.Net.Mail.Attachmentクラス添付ファイルを表すクラスです。
System.Net.NetworkCredential認証情報を表すクラスです。
System.Net.Mail.MailPriority列挙体メールの優先度を表す列挙体です。

CDO(Microsoft Collaboration Data Objects)
 Windowsでは、メールの送信機能として『CDO』を用意しています。
 CDOは、VB6やEXCEL VBA等からも利用することができますが、
 インタフェースがわかりにくいものでした。
 .NETでは、CDOの呼び出しをカプセル化することで、
 よりわかりやすいインタフェースを提供しています。
・参考文献
 『MSDN Library for VisualStudio2008日本語版』
 
以下にサンプルソースを示します
''' <summary>
''' メールを送信する
''' </summary>
''' <param name="argSmtpServer">SMTPサーバ名</param>
''' <param name="argPortNo">ポート番号</param>
''' <param name="argSmtpAuth">SMTP認証の有無</param>
''' <param name="argUserName">認証ユーザ</param>
''' <param name="argPassword">認証パスワード</param>
''' <param name="argEnableSsl">SSLの使用有無</param>
''' <param name="argTimeout">タイムアウト(ミリ秒)(Nothingで100000)</param>
''' <param name="argFrom">メールアドレス(From)</param>
''' <param name="argTo">メールアドレス(To)</param>
''' <param name="argCc">メールアドレス(Cc)</param>
''' <param name="argBcc">メールアドレス(Bcc)</param>
''' <param name="argPriority">優先度</param>
''' <param name="argSubject">件名</param>
''' <param name="argBody">本文</param>
''' <param name="argIsHtml">HTMLかどうか</param>
''' <param name="argFile">添付ファイル</param>
''' <param name="argSubEnc">エンコード(件名)</param>
''' <param name="argBodyEnc">エンコード(本文)</param>
''' <remarks></remarks>
Private Sub SendMail( _
    ByVal argSmtpServer As String, _
    ByVal argPortNo As Integer, _
    ByVal argSmtpAuth As Boolean, _
    ByVal argUserName As String, _
    ByVal argPassword As String, _
    ByVal argEnableSsl As Boolean, _
    ByVal argTimeout As Integer?, _
    ByVal argFrom As String, _
    ByVal argTo() As String, _
    ByVal argCc() As String, _
    ByVal argBcc() As String, _
    ByVal argPriority As System.Net.Mail.MailPriority, _
    ByVal argSubject As String, _
    ByVal argBody As String, _
    ByVal argIsHtml As Boolean, _
    ByVal argFile() As System.IO.FileInfo, _
    ByVal argSubEnc As String, _
    ByVal argBodyEnc As String _
    )
    'SMTPサーバを設定
    '※サーバ名、ポート番号を設定
    Dim sClient As New System.Net.Mail.SmtpClient( _
        argSmtpServer, argPortNo _
    )

    'SMTP認証の設定
    If argSmtpAuth Then
        '認証が必要な場合は、ユーザ名とパスワードを設定
        sClient.Credentials = New System.Net.NetworkCredential( _
            argUserName, argPassword _
        )
    End If

    'SSLの使用有無を設定
    sClient.EnableSsl = argEnableSsl

    'タイムアウトを設定
    If argTimeout.HasValue Then
        sClient.Timeout = argTimeout
    End If

    'メールの設定
    Dim mail As New System.Net.Mail.MailMessage
    Try
        'メールアドレス(From)
        mail.From = New System.Net.Mail.MailAddress(argFrom)
        '※メールアドレス(To)を設定
        If Not (argTo Is NothingThen
            For Each addr As String In argTo
                mail.To.Add(addr)
            Next
        End If
        'メールアドレス(Cc)
        If Not (argCc Is NothingThen
            For Each addr As String In argCc
                mail.CC.Add(addr)
            Next
        End If
        'メールアドレス(Bcc)
        If Not (argBcc Is NothingThen
            For Each addr As String In argBcc
                mail.Bcc.Add(addr)
            Next
        End If

        '優先度
        '   高い:System.Net.Mail.MailPriority.High
        '   普通:System.Net.Mail.MailPriority.Normal
        '   低い:System.Net.Mail.MailPriority.Low
        mail.Priority = argPriority
        '件名を設定
        mail.Subject = argSubject
        '本文を設定
        mail.Body = argBody
        '本文をHTML形式にするかどうか
        mail.IsBodyHtml = argIsHtml
        '添付ファイル
        If Not (argFile Is NothingThen
            For Each f As FileInfo In argFile
                mail.Attachments.Add( _
                    New System.Net.Mail.Attachment(f.FullName))
            Next
        End If
        'エンコード(件名)
        '例:shift_jis、iso-2022-jp
        mail.SubjectEncoding = Encoding.GetEncoding(argSubEnc)
        'エンコード(本文)
        mail.BodyEncoding = Encoding.GetEncoding(argBodyEnc)

        'メールを送信
        sClient.Send(mail)
    Finally
        mail.Dispose()
    End Try
End Sub
[VB.NET]メールを送信するサンプル

/// <summary>
/// メールを送信する
/// </summary>
/// <param name="argSmtpServer">SMTPサーバ名</param>
/// <param name="argPortNo">ポート番号</param>
/// <param name="argSmtpAuth">SMTP認証の有無</param>
/// <param name="argUserName">認証ユーザ</param>
/// <param name="argPassword">認証パスワード</param>
/// <param name="argEnableSsl">SSLの使用有無</param>
/// <param name="argTimeout">タイムアウト(ミリ秒)(nullで100000)</param>
/// <param name="argFrom">メールアドレス(From)</param>
/// <param name="argTo">メールアドレス(To)</param>
/// <param name="argCc">メールアドレス(Cc)</param>
/// <param name="argBcc">メールアドレス(Bcc)</param>
/// <param name="argPriority">優先度</param>
/// <param name="argSubject">件名</param>
/// <param name="argBody">本文</param>
/// <param name="argIsHtml">HTMLかどうか</param>
/// <param name="argFile">添付ファイル</param>
/// <param name="argSubEnc">エンコード(件名)</param>
/// <param name="argBodyEnc">エンコード(本文)</param>
/// <remarks></remarks>
private void SendMail(
    string argSmtpServer, int argPortNo, bool argSmtpAuth, 
    string argUserName, string argPassword, bool argEnableSsl, 
    int? argTimeout, string argFrom, 
    string[] argTo, string[] argCc, string[] argBcc, 
    System.Net.Mail.MailPriority argPriority, 
    string argSubject, string argBody, bool argIsHtml, 
    System.IO.FileInfo[] argFile, 
    string argSubEnc, string argBodyEnc)
{
    //SMTPサーバを設定
    //※サーバ名、ポート番号を設定
    System.Net.Mail.SmtpClient sClient = 
        new System.Net.Mail.SmtpClient(argSmtpServer, argPortNo);
    
    //SMTP認証の設定
    if (argSmtpAuth) {
        //認証が必要な場合は、ユーザ名とパスワードを設定
        sClient.Credentials = 
            new System.Net.NetworkCredential(
                argUserName, argPassword);
    }
    
    //SSLの使用有無を設定
    sClient.EnableSsl = argEnableSsl;
    
    //タイムアウトを設定
    if (argTimeout.HasValue) {
        sClient.Timeout = argTimeout;
    }
    
    //メールの設定
    System.Net.Mail.MailMessage mail = 
        new System.Net.Mail.MailMessage();
    try {
        //メールアドレス(From)
        mail.From = new System.Net.Mail.MailAddress(argFrom);
        //※メールアドレス(To)を設定
        if (argTo != null) {
            foreach (string addr in argTo) {
                mail.To.Add(addr);
            }
        }
        //メールアドレス(Cc)
        if (argCc != null) {
            foreach (string addr in argCc) {
                mail.CC.Add(addr);
            }
        }
        //メールアドレス(Bcc)
        if (argBcc != null) {
            foreach (string addr in argBcc) {
                mail.Bcc.Add(addr);
            }
        }
        
        //優先度
        // 高い:System.Net.Mail.MailPriority.High
        // 普通:System.Net.Mail.MailPriority.Normal
        // 低い:System.Net.Mail.MailPriority.Low
        mail.Priority = argPriority;
        //件名を設定
        mail.Subject = argSubject;
        //本文を設定
        mail.Body = argBody;
        //本文をHTML形式にするかどうか
        mail.IsBodyHtml = argIsHtml;
        //添付ファイル
        if (argFile != null) {
            foreach (FileInfo f in argFile) {
                mail.Attachments.Add(
                    new System.Net.Mail.Attachment(f.FullName));
            }
        }
        //エンコード(件名)
        //例:shift_jis、iso-2022-jp
        mail.SubjectEncoding = Encoding.GetEncoding(argSubEnc);
        //エンコード(本文)
        mail.BodyEncoding = Encoding.GetEncoding(argBodyEnc);
        
        //メールを送信
        sClient.Send(mail);
    }
    finally {
        mail.Dispose();
    }
}
[C#]メールを送信するサンプル
補足
本サンプルは、送信元メールアドレスをYahooメールで確認しています。(2008.12.29現在)
Yahooメールで確認するには、
『Yahooメールを他のメーラーで送受信できるようにする』必要があります。
Yahooメールの『POPアクセスとメール転送』で、『ブラウザアクセスとPOPアクセス』に設定して下さい。
あとは、
ユーザ名:YahooID
パスワード:YahooIDのパスワード
SMTPサーバ:『smtp.mail.yahoo.co.jp』
SMTPのポート番号:『587』
でメールを送信できます。

[.NET]関数(y=f(x))のグラフをImageに描画する [Programming .NET Tips]

[ポイント]
・関数(y=f(x))の呼び出しは、デリゲート経由で行います。
 これにより、描画メソッド(DrawFunctionメソッド)を変更することなく、
 関数(y=f(x))を切替えることができます。
・非関数(xとyが1対1に対応していない)には対応していません。
 例えば、x2+y2=r2のような円を表すグラフは描画できません。
・Graphics.DrawLineメソッドで、一つ前の座標との直線を描画している為、
 連続していない関数(離散型)では一部正しく描画されないことがあります。
 例えば、y=tan(x)の場合、x=π/2で縦線が描画されます。
''' <summary>
''' 関数(y=f(x))のデリゲート
''' </summary>
''' <param name="x">入力</param>
''' <returns>出力</returns>
''' <remarks></remarks>
Public Delegate Function FuncHandler(ByVal x As IntegerAs Integer

''' <summary>
''' 関数(y=f(x))のグラフをイメージに描画する。
''' </summary>
''' <param name="targetImage">描画対象のイメージ</param>
''' <param name="fnc">関数(y=f(x))</param>
''' <param name="xFrom">X座標の最小値</param>
''' <param name="xTo">X座標の最大値</param>
''' <remarks></remarks>
Public Shared Sub DrawFunction( _
    ByVal targetImage As Image, ByVal fnc As FuncHandler, _
    ByVal xFrom As IntegerByVal xTo As Integer)

    Dim g As Graphics = Nothing

    Try
        g = Graphics.FromImage(targetImage)

        '描画領域を初期化(白で塗りつぶす)
        g.FillRectangle(Brushes.White, 0, 0, _
            targetImage.Width, targetImage.Height)

        '描画領域の原点を中央に移動
        Dim xMax As Integer = targetImage.Width * 0.5
        Dim xMin As Integer = -1 * xMax
        Dim yMax As Integer = targetImage.Height * 0.5
        Dim yMin As Integer = -1 * yMax
        g.TranslateTransform(xMax, yMax)
        '描画領域のY座標の向きを逆にする(Y座標の上方向をプラスにする)
        g.ScaleTransform(1, -1)

        '格子を描画する(水平線)
        For y As Single = 0 To yMax Step 10
            g.DrawLine(Pens.Cyan, xMin, y, xMax, y)
        Next
        For y As Single = 0 To yMin Step -10
            g.DrawLine(Pens.Cyan, xMin, y, xMax, y)
        Next

        '格子を描画する(垂直線)
        For x As Single = 0 To xMax Step 10
            g.DrawLine(Pens.Cyan, x, yMin, x, yMax)
        Next
        For x As Single = 0 To xMin Step -10
            g.DrawLine(Pens.Cyan, x, yMin, x, yMax)
        Next

        'X軸を描画
        g.DrawLine(Pens.Blue, xMin, 0, xMax, 0)
        'Y軸を描画
        g.DrawLine(Pens.Blue, 0, yMin, 0, yMax)

        '関数のグラフを描画
        For x As Integer = xFrom To xTo
            Try
                g.DrawLine( _
                    Pens.Black, x - 1, _
                    fnc.Invoke(x - 1), x, fnc.Invoke(x))
            Catch ex As ArithmeticException
                'ゼロ除算、数値演算のオーバーフロー、
                '定義されていない演算エラーは無視する
            End Try
        Next
    Finally
        If Not (g Is NothingThen
            g.Dispose()
        End If
    End Try
End Sub
[VB.NET]関数のグラフをImageに描画する例

(1)PictureBoxに、一次関数(y=2x)のグラフを描画する例
・上記で定義したメソッド(DrawFunction)の使用例を以下に示します。
 まずは、一次関数(y=2x)を定義します。
''' <summary>
''' 関数(一次関数)
''' </summary>
''' <param name="x">入力</param>
''' <returns>出力</returns>
''' <remarks></remarks>
Public Function fnc1(ByVal x As IntegerAs Integer
    Return x * 2
End Function
[VB.NET]例:一次関数の定義

・適当なイベント処理内で、DrawFunctionメソッドを呼ぶ処理を記述します。
 DrawFunctionメソッドに渡す引数は、
 ・グラフを描画するImageインスタンス
 ・一次関数(y=2x)のデリゲート (※デリゲートとはメソッドの参照を格納する変数、型です。)
 ・X座標の範囲(From、To)
 です。
 [デリゲートについて]
  .NETでは、メソッドの参照を変数に格納し、変数経由でメソッドに
  アクセスすることができます。 (デリゲート変数)
  この例では、一次関数の定義をデリゲート変数に格納し、DrawFunctionメソッドに渡します。
  メソッドの参照はAddressOf演算子で取得します。
  デリゲート変数はFuncHandler型で定義し、fnc1と関連付けします。
Private Sub Button1_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles Button1.Click
    Dim img As New Bitmap(Me.PictureBox1.Width, Me.PictureBox1.Height)

    '関数の参照をデリゲート変数に格納する
    '※関数を変更する場合は、デリゲート変数の中身を変更する。
    Dim f As New FuncHandler(AddressOf Me.fnc1)
    '関数のグラフを描画する。
    DrawFunction(img, f, img.Width * -0.5, img.Width * 0.5)

    Me.PictureBox1.Image = img
End Sub
[VB.NET]DrawFunctionメソッドの呼び出し
実行結果
一次関数

(2)PictureBoxに、二次関数のグラフを描画する例
・デリゲート変数の内容を、二次関数のデリゲートに置き換えるだけで、描画内容を変更できます。
''' <summary>
''' 関数(二次関数)
''' </summary>
''' <param name="x">入力</param>
''' <returns>出力</returns>
''' <remarks></remarks>
Public Function fnc1(ByVal x As IntegerAs Integer
    Return 0.05 * (x - 10) * (x + 50)
End Function
[VB.NET]関数を二次関数で定義した場合
実行結果
関数を二次関数で定義した場合
(3)PictureBoxに、三角関数のグラフを描画する例
・同様に三角関数も描画可能です。
''' <summary>
''' 関数(三角関数)
''' </summary>
''' <param name="x">入力</param>
''' <returns>出力</returns>
''' <remarks></remarks>
Public Function fnc1(ByVal x As IntegerAs Integer
    Return 50 * Math.Sin(x / 15)
End Function
[VB.NET]関数を三角関数で定義した場合
実行結果
関数を三角関数で定義した場合
(4)PictureBoxに、平方根の関数のグラフを描画する例
・平方根の関数も同様です。
''' <summary>
''' 関数(平方根)
''' </summary>
''' <param name="x">入力</param>
''' <returns>出力</returns>
''' <remarks></remarks>
Public Function fnc1(ByVal x As IntegerAs Integer
    Return 10 * Math.Sqrt(x)
End Function
[VB.NET]関数を平方根で定義した場合
実行結果
関数を平方根で定義した場合

[Algo]和と積から元の2数の算出 [Programming Algorithm]

[はじめに]
(1)ある2数の和と積から、元の2数を求めるアルゴリズムです。
   例えば、『足して5』、『掛けて6』になる2つの数は、
   になります。
   これを解くアルゴリズムとして、
   2次方程式の解の解法を利用することができます。

   具体的には、
   Xについての2次方程式
   2-5X+6=0 は因数分解すると、
   (X-2)(X-3)=0 となり、
   解はX=2、3 となります。

   つまり、
   2-(α+β)X+αβ=0 の解が、
   X=α、β となることを利用することで、
   元の2数を求めることができます。

   α+β=Aαβ=Bとした時、
   2次方程式の解の公式から、
   2-AX+B=0 
   X= {A±(A2 - 4B)1/2} / 2 となり、 
   求める2数は、
   X= {A+(A2 - 4B)1/2} / 2 と
   X= {A-(A2 - 4B)1/2} / 2
   となります。

   また、2次方程式の判別式が負数の場合、
   つまり2次方程式の実数解が存在しない場合は、
   元の2数が存在しないので、解を算出する前にチェックする必要があります。

[参考]2次方程式の解の公式
E784A1E9A18C.jpg
[ソース]
''' <summary>
''' 和(α+β)と積(α×β)から、αとβを算出する。
''' </summary>
''' <param name="sum">和(α+β)</param>
''' <param name="product">積(α×β)</param>
''' <returns>αとβ(存在しない場合はNothing)</returns>
''' <remarks></remarks>
Public Shared Function CalcValueBySumProduct(ByVal sum As IntegerByVal product As IntegerAs Decimal()
    'α、βの算出に
    '2次方程式の解の公式を利用する。
    '   以下の2次方程式を解くと、X=α、βになることを利用して、
    '   X*X - (α+β)*X + α*β = 0
    '   を解く。
    '   X= [(α+β)±√{(α+β)*(α+β) - 4*α*β}] / 2
    '補足
    '   実数解が存在しない場合は、解が存在しないものとする。
    Dim dist As Decimal = sum * sum - 4 * product

    If dist < 0 Then
        Return Nothing
    End If

    Dim sqrtDist As Decimal = Math.Sqrt(dist)
    Dim rtnValue() As Decimal = New Decimal(1) {}
    rtnValue(0) = (sum - sqrtDist) / 2
    rtnValue(1) = (sum + sqrtDist) / 2

    Return rtnValue
End Function
[VB.NET]和と積から元の2数を算出する。

[.NET]Imageの分割 [Programming .NET Tips]

ファイルから取り込んだImageを複数に分割する機会があったので、
作ってみました。

[ポイント]
(1)Imageオブジェクトを指定した個数で分割します。
   例:縦5個、横10個と指定すると、5×10の2次元配列でImageを作成します。
(2)Imageを分割するには、
   Graphics.DrawImage(Image, Integer, Integer, Rectangle, GraphicsUnit)
   を使います。
(3)参考文献
   『MSDN Library for VisualStudio2008日本語版』

[ソース]
''' <summary>
''' 指定したImageを分割する。
''' </summary>
''' <param name="originalImage">オリジナルImage</param>
''' <param name="verticalNum">分割数(垂直)</param>
''' <param name="horizontalNum">分割数(水平)</param>
''' <returns>分割済Image</returns>
''' <remarks></remarks>
Public Shared Function DivideImage( _
    ByVal originalImage As Image, _
    ByVal verticalNum As IntegerByVal horizontalNum As Integer _
    ) As Image()()

    '引数チェック
    If originalImage Is Nothing Then
        Throw New ArgumentNullException("originalImage is null")
    End If

    If verticalNum < 1 Then
        Throw New ArgumentOutOfRangeException("verticalNum < 1")
    End If

    If horizontalNum < 1 Then
        Throw New ArgumentOutOfRangeException("horizontalNum < 1")
    End If

    Dim g As Graphics = Nothing

    Dim rtnImage()() As Image = New Image(verticalNum - 1)() {}
    For i As Integer = 0 To verticalNum - 1
        rtnImage(i) = New Image(horizontalNum - 1) {}
    Next

    Dim originalSize As Size = originalImage.Size
    Dim divWidth As Integer = originalSize.Width / horizontalNum
    Dim divHeight As Integer = originalSize.Height / verticalNum

    For vCnt As Integer = 0 To verticalNum - 1
        For hCnt As Integer = 0 To horizontalNum - 1
            Try
                '空のImageを作成
                rtnImage(vCnt)(hCnt) = New Bitmap(divWidth, divHeight)
                'Imageを描画する為のGraphicsオブジェクトを作成
                g = System.Drawing.Graphics.FromImage( _
                       rtnImage(vCnt)(hCnt))
                'オリジナルImageから描画対象の領域を算出
                '[補足]
                '   領域の開始座標を
                '   ・hCnt * divWidth
                '   ・vCnt * divHeight
                '   ではなく、
                '   ・hCnt * originalSize.Width / horizontalNum
                '   ・vCnt * originalSize.Height / verticalNum
                '   にしているのは、誤差を軽減する為です。
                Dim rect As New Rectangle( _
                    hCnt * originalSize.Width / horizontalNum, _
                    vCnt * originalSize.Height / verticalNum, _
                    divWidth, _
                    divHeight _
                    )
                'オリジナルImageの内容を描画
                g.DrawImage( _
                     originalImage, 0, 0, rect, GraphicsUnit.Pixel)
            Finally
                If Not (g Is NothingThen
                    'Graphicsオブジェクトを解放
                    g.Dispose()
                End If
            End Try
        Next
    Next

    Return rtnImage
End Function
[VB.NET]Imageを分割する例


/// <summary>
/// 指定したImageを分割する。
/// </summary>
/// <param name="originalImage">オリジナルImage</param>
/// <param name="verticalNum">分割数(垂直)</param>
/// <param name="horizontalNum">分割数(水平)</param>
/// <returns>分割済Image</returns>
/// <remarks></remarks>
public static Image[][] DivideImage(
    Image originalImage, int verticalNum, int horizontalNum)
{
    
    //引数チェック
    if (originalImage == null) {
        throw new ArgumentNullException("originalImage is null");
    }
    
    if (verticalNum < 1) {
        throw new ArgumentOutOfRangeException("verticalNum < 1");
    }
    
    if (horizontalNum < 1) {
        throw new ArgumentOutOfRangeException("horizontalNum < 1");
    }
    
    Graphics g = null;
    
    Image[][] rtnImage = new Image[verticalNum][];
    for (int i = 0; i <= verticalNum - 1; i++) {
        rtnImage(i) = new Image[horizontalNum];
    }
    
    Size originalSize = originalImage.Size;
    int divWidth = originalSize.Width / horizontalNum;
    int divHeight = originalSize.Height / verticalNum;
    
    for (int vCnt = 0; vCnt < verticalNum ; vCnt++) {
        for (int hCnt = 0; hCnt < horizontalNum ; hCnt++) {
            try {
                //空のImageを作成
                rtnImage(vCnt)(hCnt) = new Bitmap(divWidth, divHeight);
                //Imageを描画する為のGraphicsオブジェクトを作成
                g = System.Drawing.Graphics.FromImage(
                    rtnImage(vCnt)(hCnt));
                //オリジナルImageから描画対象の領域を算出
                //[補足]
                // 領域の開始座標を
                // ・hCnt * divWidth
                // ・vCnt * divHeight
                // ではなく、
                // ・hCnt * originalSize.Width / horizontalNum
                // ・vCnt * originalSize.Height / verticalNum
                // にしているのは、誤差を軽減する為です。
                Rectangle rect = new Rectangle(
                     hCnt * originalSize.Width / horizontalNum, 
                     vCnt * originalSize.Height / verticalNum, 
                     divWidth, divHeight);
                //オリジナルImageの内容を描画
                g.DrawImage(
                    originalImage, 0, 0, 
                    rect, GraphicsUnit.Pixel);
            }
            finally {
                if (g != null) {
                    //Graphicsオブジェクトを解放
                    g.Dispose();
                }
            }
        }
    }
    
    return rtnImage;
}
[C#]Imageを分割する例

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。