画像をバイト配列に変換する方法


125

画像をバイト配列に、またはその逆に変換する方法を誰かが提案できますか?

私はWPFアプリケーションを開発していて、ストリームリーダーを使用しています。

回答:


174

画像をバイト配列に変更するサンプルコード

public byte[] ImageToByteArray(System.Drawing.Image imageIn)
{
   using (var ms = new MemoryStream())
   {
      imageIn.Save(ms,imageIn.RawFormat);
      return  ms.ToArray();
   }
}

C#Image to Byte ArrayおよびByte Array to Image Converter Class


12
の代わりにSystem.Drawing.Imaging.ImageFormat.Gif使用できますimageIn.RawFormat
S.Serpooshan

1
これは再現性がないようです、または少なくとも数回の変換後に、奇妙なGDI +エラーが発生し始めます。以下にあるImageConverter解決策は、これらのエラーを回避するようです。
Dave Cousineau 2017

現在、pngを使用する方が良いかもしれません。
Nyerguds

余談ですが、これには必要のない追加のメタデータが含まれている可能性があります;-)メタデータを削除するには、新しいビットマップを作成して、それに画像を渡すことができ(new Bitmap(imageIn)).Save(ms, imageIn.RawFormat);ます。
Markus Safar

56

Imageオブジェクトを変換するにbyte[]は、次のようにします。

public static byte[] converterDemo(Image x)
{
    ImageConverter _imageConverter = new ImageConverter();
    byte[] xByte = (byte[])_imageConverter.ConvertTo(x, typeof(byte[]));
    return xByte;
}

4
完璧な答え!....「画像ファイルの拡張子」を定義する必要はありません。まさに私が探していたものです。
ブラボー

1
余談ですが、これには必要のない追加のメタデータが含まれている可能性があります;-)メタデータを削除するには、新しいビットマップを作成して、それに画像を渡すことができ.ConvertTo(new Bitmap(x), typeof(byte[]));ます。
Markus Safar

1
私にとって、Visual StudioはImageConverterのタイプを認識していません。これを使用するために必要なインポートステートメントはありますか?
technoman23

32

画像パスからバイト配列を取得する別の方法は、

byte[] imgdata = System.IO.File.ReadAllBytes(HttpContext.Current.Server.MapPath(path));

彼らの質問にはWPFのタグが付けられており(サーバーで実行されていると考えてMapPathを含める必要はありません)、すでにイメージがあることを示しています(ディスクからイメージを読み取る理由はなく、そもそもディスク上にあるとは限りません)。申し訳ありませんが、あなたの返信は質問とはまったく関係がないようです
Ronan Thibaudau

19

これが私が現在使用しているものです。ピクセルのビット深度を変更したり(24ビット対32ビット)、画像の解像度(dpi)を無視したりして、私が試した他のテクニックの一部は最適ではありませんでした。

  // ImageConverter object used to convert byte arrays containing JPEG or PNG file images into 
  //  Bitmap objects. This is static and only gets instantiated once.
  private static readonly ImageConverter _imageConverter = new ImageConverter();

画像をバイト配列に:

  /// <summary>
  /// Method to "convert" an Image object into a byte array, formatted in PNG file format, which 
  /// provides lossless compression. This can be used together with the GetImageFromByteArray() 
  /// method to provide a kind of serialization / deserialization. 
  /// </summary>
  /// <param name="theImage">Image object, must be convertable to PNG format</param>
  /// <returns>byte array image of a PNG file containing the image</returns>
  public static byte[] CopyImageToByteArray(Image theImage)
  {
     using (MemoryStream memoryStream = new MemoryStream())
     {
        theImage.Save(memoryStream, ImageFormat.Png);
        return memoryStream.ToArray();
     }
  }

画像へのバイト配列:

  /// <summary>
  /// Method that uses the ImageConverter object in .Net Framework to convert a byte array, 
  /// presumably containing a JPEG or PNG file image, into a Bitmap object, which can also be 
  /// used as an Image object.
  /// </summary>
  /// <param name="byteArray">byte array containing JPEG or PNG file image or similar</param>
  /// <returns>Bitmap object if it works, else exception is thrown</returns>
  public static Bitmap GetImageFromByteArray(byte[] byteArray)
  {
     Bitmap bm = (Bitmap)_imageConverter.ConvertFrom(byteArray);

     if (bm != null && (bm.HorizontalResolution != (int)bm.HorizontalResolution ||
                        bm.VerticalResolution != (int)bm.VerticalResolution))
     {
        // Correct a strange glitch that has been observed in the test program when converting 
        //  from a PNG file image created by CopyImageToByteArray() - the dpi value "drifts" 
        //  slightly away from the nominal integer value
        bm.SetResolution((int)(bm.HorizontalResolution + 0.5f), 
                         (int)(bm.VerticalResolution + 0.5f));
     }

     return bm;
  }

編集:jpgまたはpngファイルから画像を取得するには、File.ReadAllBytes()を使用してファイルをバイト配列に読み込む必要があります。

 Bitmap newBitmap = GetImageFromByteArray(File.ReadAllBytes(fileName));

これにより、ソースストリームを開いたままにしておくことを望むビットマップに関連する問題と、ソースファイルがロックされたままになるその問題に対するいくつかの回避策が回避されます。


これをテストしている間に、私は結果のビットマップを取り、それを使用してバイト配列に戻しImageConverter _imageConverter = new ImageConverter(); lock(SourceImage) { return (byte[])_imageConverter.ConvertTo(SourceImage, typeof(byte[])); } ます。これは通常、約100回の反復後に発生しますが、使用new Bitmap(SourceFileName);してビットマップを取得し、そのコードを実行すると、正常に機能します。
Don

@ドン:本当に良いアイデアはありません。どの画像が入力と同じ出力にならないかは一貫していますか?予想と異なる場合に、なぜ出力が異なるのかを確認しようとしましたか?あるいは、それは本当に重要ではないかもしれません、そして、人は「事が起こる」ことを受け入れることができます。
レニーペット

それは一貫して起こっていました。原因はわかりませんが。メモリ割り当ての4Kバイト境界と関係があるのではないかと感じています。しかし、それは簡単に間違っている可能性があります。BinaryFormatterでMemoryStreamを使用するように切り替えたところ、検証のために1000回以上ループした、さまざまなフォーマットとサイズの250を超えるテスト画像でテストしたところ、非常に一貫性を保つことができました。返信してくれてありがとう。
Don

17

これを試して:

public byte[] imageToByteArray(System.Drawing.Image imageIn)
{
    MemoryStream ms = new MemoryStream();
    imageIn.Save(ms,System.Drawing.Imaging.ImageFormat.Gif);
    return ms.ToArray();
}

public Image byteArrayToImage(byte[] byteArrayIn)
{
    MemoryStream ms = new MemoryStream(byteArrayIn);
    Image returnImage = Image.FromStream(ms);
    return returnImage;
}

imageToByteArray(System.Drawing.Image imageIn)imageInは、画像パスまたはこれで画像を渡す方法です
Shashank

これは、画像をバイト配列に変換したり、バイト配列に戻したりする必要があるときにいつでも行います。
Alex Essilfie 2010

あなたはメモリストリームを閉じるのを忘れました...これは次から直接コピーされます:link
Qwerty01

1
@ Qwerty01 Disposeを呼び出してMemoryStreamも、少なくとも現在の実装では、より高速に使用されているメモリはクリーンアップされません。実際、それを閉じると、Image後で使用できなくなり、GDIエラーが発生します。
Saeb Amini、2015

14

File.ReadAllBytes()メソッドを使用して、任意のファイルをバイト配列に読み込むことができます。バイト配列をファイルに書き込むには、File.WriteAllBytes()メソッドを使用します。

お役に立てれば。

詳細とサンプルコードはこちらからご覧いただけます


余談ですが、これには必要のない追加のメタデータが含まれる可能性があります;-)
Markus Safar

1
多分。私はこの回答を10年前に書きました。
シェカール

5

ピクセルまたはイメージ全体(ヘッダーを含む)のみをバイト配列として必要ですか?

ピクセルの場合:CopyPixelsビットマップのメソッドを使用します。何かのようなもの:

var bitmap = new BitmapImage(uri);

//Pixel array
byte[] pixels = new byte[width * height * 4]; //account for stride if necessary and whether the image is 32 bit, 16 bit etc.

bitmap.CopyPixels(..size, pixels, fullStride, 0); 

3

コード:

using System.IO;

byte[] img = File.ReadAllBytes(openFileDialog1.FileName);

1
彼がファイルを読み取っている場合にのみ機能します(それでもフォーマットされた/圧縮されたバイトを取得し、BMPでない限り生のバイトは取得しません)
BradleyDotNET

3

ストリームのバイトを運ぶためにimageBytesを参照しない場合、メソッドは何も返しません。imageBytes = m.ToArray();を参照してください。

    public static byte[] SerializeImage() {
        MemoryStream m;
        string PicPath = pathToImage";

        byte[] imageBytes;
        using (Image image = Image.FromFile(PicPath)) {

            using ( m = new MemoryStream()) {

                image.Save(m, image.RawFormat);
                imageBytes = new byte[m.Length];
               //Very Important    
               imageBytes = m.ToArray();

            }//end using
        }//end using

        return imageBytes;
    }//SerializeImage

[NB]それでもブラウザに画像が表示されない場合は、詳細なトラブルシューティング手順を書きました

解決しました!-iis-not-serving-css、-images-and-javascript


1

これは、任意のタイプの画像(PNG、JPG、JPEGなど)をバイト配列に変換するためのコードです。

   public static byte[] imageConversion(string imageName){            


        //Initialize a file stream to read the image file
        FileStream fs = new FileStream(imageName, FileMode.Open, FileAccess.Read);

        //Initialize a byte array with size of stream
        byte[] imgByteArr = new byte[fs.Length];

        //Read data from the file stream and put into the byte array
        fs.Read(imgByteArr, 0, Convert.ToInt32(fs.Length));

        //Close a file stream
        fs.Close();

        return imageByteArr
    }

余談ですが、これには必要のない追加のメタデータが含まれる可能性があります;-)
Markus Safar

0

画像をバイト配列に変換します。コードは以下のとおりです。

public byte[] ImageToByteArray(System.Drawing.Image images)
{
   using (var _memorystream = new MemoryStream())
   {
      images.Save(_memorystream ,images.RawFormat);
      return  _memorystream .ToArray();
   }
}

バイト配列を画像に変換しA Generic error occurred in GDI+ます。コードは次のとおりです。コードは画像保存のハンドルです。

public void SaveImage(string base64String, string filepath)
{
    // image convert to base64string is base64String 
    //File path is which path to save the image.
    var bytess = Convert.FromBase64String(base64String);
    using (var imageFile = new FileStream(filepath, FileMode.Create))
    {
        imageFile.Write(bytess, 0, bytess.Length);
        imageFile.Flush();
    }
}

-2

このコードは、SQLSERVER 2012のテーブルから最初の100行を取得し、行ごとの画像をファイルとしてローカルディスクに保存します

 public void SavePicture()
    {
        SqlConnection con = new SqlConnection("Data Source=localhost;Integrated security=true;database=databasename");
        SqlDataAdapter da = new SqlDataAdapter("select top 100 [Name] ,[Picture] From tablename", con);
        SqlCommandBuilder MyCB = new SqlCommandBuilder(da);
        DataSet ds = new DataSet("tablename");
        byte[] MyData = new byte[0];
        da.Fill(ds, "tablename");
        DataTable table = ds.Tables["tablename"];
           for (int i = 0; i < table.Rows.Count;i++ )               
               {
                DataRow myRow;
                myRow = ds.Tables["tablename"].Rows[i];
                MyData = (byte[])myRow["Picture"];
                int ArraySize = new int();
                ArraySize = MyData.GetUpperBound(0);
                FileStream fs = new FileStream(@"C:\NewFolder\" + myRow["Name"].ToString() + ".jpg", FileMode.OpenOrCreate, FileAccess.Write);
                fs.Write(MyData, 0, ArraySize);
                fs.Close();
               }

    }

注意:NewFolder名のディレクトリはC:\に存在する必要があります


3
あなたは間違った質問に答えた...まあ、私は願っています^ _ ^
JiBéDoublevé
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.