C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.87529 の関連記事表示

<< 0 >>
■87529  Re[3]: Icon について
□投稿者/ 魔界の仮面弁士 -(2018/06/01(Fri) 12:04:22)
    No87528 (夜叉丸 さん) に返信
    > データの後半部分のデータが消えています。
    > データサイズが正常な953バイトに対して682バイトしかなかったです。

    連続実行させて検証していないので、思いつきになりますが、
    > Icon icon = System.Drawing.Icon.FromHandle((new Bitmap(ms)).GetHicon());
    HICON からの読み取り中に、Bitmap が Dispose されてしまったとか?
    うーん。すぐには思い当たらないです。


    >  byte[] ret = ms.GetBuffer();
    GetBuffer には、未使用バイト領域が含まれる可能性がありえます。

    今回は問題無いとしても、念のため ToArray を使った方が良いと思いますよ。
    あるいは TryGetBuffer メソッドでも良いですけど。
    http://8thway.blogspot.com/2015/12/memorystream.html


    ちなみに、
      MemoryStream ms = new MemoryStream();
      ms.Write(Enumerable.Repeat(byte.MaxValue, 1024).ToArray(), 0, 1024);
      ms.WriteByte(byte.MaxValue);
      int i1 = ms.Capacity;
      int i2 = (int)ms.Length;
      byte[] b1 = ms.GetBuffer();
      byte[] b2 = ms.ToArray();
      ArraySegment<byte> b3; ms.TryGetBuffer(out b3);
      ms.Close();
    というコードの場合、
      i1 は 2048 (バッファ長)
      i2 は 1025 (実データ長)
      b1.Length は 2048 (バッファ長)
      b2.Length は 1025 (実データ長)
      b3 は .Offset = 0, .Count = 1025, .Array.Length = 2048
    という結果になりますね。



    > private byte[] GetBytearrayFromIcon(Icon icon)
    >  Bitmap bmp = icon.ToBitmap();

    > private Icon GetIconFromByteArray(byte[] bytes)
    >  bmp.Save(ms, ImageFormat.Png);

    .ico フォーマットではなく .png フォーマットで永続化しているのは、
    意図的なものでしょうか。


    もしも Ico 形式のまま無加工で永続化するなら、こんな感じで書けそうです。

    // 利用方法:
    //  byte[] binary = srcIcon.ToBinary();
    //  Icon dstIcon = bin.ToIcon();
    public static class IconExtensions
    {
     public static byte[] ToBinary(this Icon ico)
     {
      using (var ms = new MemoryStream())
      {
       ico.Save(ms);
       ms.Flush();
       return ms.ToArray();
      }
     }

     public static Icon FromBinary(this byte[] binary)
     {
      using (var ms = new MemoryStream(binary))
      {
       try { return new Icon(ms); } catch { return null; }
      }
     }
    }



    なお、画像の先頭 4 バイト見ることで、.ico / .png の判定ができます。

    byte[] bin4 = BinaryOfYourIcon.Take(4).ToArray();
    bool isIco = bin4.SequenceEqual(new byte[] { 0x00, 0x00, 0x01, 0x00 });
    bool isPng = bin4.SequenceEqual(new byte[] { 0x89, (byte)'P', (byte)'N', (byte)'G' });


    .ico 形式の場合、ファイル先頭の 0x00, 0x00, 0x01, 0x00 の後に続く 2 バイトが、
    格納されているアイコンの数を表します。

    System.Drawing.Icon の場合、それぞれのアイコンを個別に取り出す機能がありませんので、
    正確な画像データを得たい場合には No87527 で紹介した IconLib 等を利用してみてください。
記事No.87523 のレス /過去ログ150より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -