バイト配列に関するすべての質問を検索しましたが、常に失敗しました。私はこれまでにc#をコーディングしたことがありません。バイト配列から画像ファイルを作成する方法を教えてください。
これは、imageData
という名前の配列にバイトを格納する私の関数です
public void imageReady( byte[] imageData, int fWidth, int fHeight))
皆さん、あなたの助けに感謝します。この答えはすべてうまくいくと思います。しかし、バイト配列には生のバイトが含まれていると思います。そのため、これらのソリューションはすべて私のコードでは機能しませんでした。
しかし、私は解決策を見つけました。たぶん、このソリューションは、私のような問題を抱えている他のコーダーを助けます。
static byte[] PadLines(byte[] bytes, int rows, int columns) {
int currentStride = columns; // 3
int newStride = columns; // 4
byte[] newBytes = new byte[newStride * rows];
for (int i = 0; i < rows; i++)
Buffer.BlockCopy(bytes, currentStride * i, newBytes, newStride * i, currentStride);
return newBytes;
}
int columns = imageWidth;
int rows = imageHeight;
int stride = columns;
byte[] newbytes = PadLines(imageData, rows, columns);
Bitmap im = new Bitmap(columns, rows, stride,
PixelFormat.Format8bppIndexed,
Marshal.UnsafeAddrOfPinnedArrayElement(newbytes, 0));
im.Save("C:\\Users\\musa\\Documents\\Hobby\\image21.bmp");
このソリューションは、8ビット256 bpp(Format8bppIndexed)で機能します。画像に別の形式がある場合は、PixelFormat
を変更する必要があります。
そして今、色に問題があります。これを解決したらすぐに、他のユーザーの回答を編集します。
* PS =ストライド値についてはわかりませんが、8ビットの場合は列と等しくなければなりません。
また、この関数は私のために機能します。この関数は、8ビットのグレースケール画像を32ビットのレイアウトにコピーします。
public void SaveBitmap(string fileName, int width, int height, byte[] imageData)
{
byte[] data = new byte[width * height * 4];
int o = 0;
for (int i = 0; i < width * height; i++)
{
byte value = imageData[i];
data[o++] = value;
data[o++] = value;
data[o++] = value;
data[o++] = 0;
}
unsafe
{
fixed (byte* ptr = data)
{
using (Bitmap image = new Bitmap(width, height, width * 4,
PixelFormat.Format32bppRgb, new IntPtr(ptr)))
{
image.Save(Path.ChangeExtension(fileName, ".jpg"));
}
}
}
}
これらのbytes
をMemoryStream
に入れる必要があります。
Bitmap bmp;
using (var ms = new MemoryStream(imageData))
{
bmp = new Bitmap(ms);
}
Bitmap(Stream stream)
コンストラクターのオーバーロードを使用します。
UPDATE:ドキュメントと、私が読んでいるソースコードによれば、ArgumentException
がスローされることに注意してくださいこれらの条件:
stream does not contain image data or is null.
-or-
stream contains a PNG image file with a single dimension greater than 65,535 pixels.
次のように簡単にできます:
var ms = new MemoryStream(imageData);
System.Drawing.Image image = Image.FromStream(ms);
image.Save("c:\\image.jpg");
テストしてみましょう:
byte[] imageData;
// Create the byte array.
var originalImage = Image.FromFile(@"C:\original.jpg");
using (var ms = new MemoryStream())
{
originalImage.Save(ms, ImageFormat.Jpeg);
imageData = ms.ToArray();
}
// Convert back to image.
using (var ms = new MemoryStream(imageData))
{
Image image = Image.FromStream(ms);
image.Save(@"C:\newImage.jpg");
}