web-dev-qa-db-fra.com

Comment créer un bitmap à partir d'un tableau d'octets?

J'ai cherché toutes les questions sur le tableau d'octets mais j'ai toujours échoué. Je n'ai jamais codé c # je suis nouveau dans ce côté. Pourriez-vous m'aider à créer un fichier image à partir d'un tableau d'octets.

Voici ma fonction qui stocke des octets dans un tableau nommé imageData

public void imageReady( byte[] imageData, int fWidth, int fHeight))
55
goGud

Les gars merci pour votre aide. Je pense que tout cela répond. Cependant, je pense que mon tableau d'octets contient des octets bruts. C'est pourquoi toutes ces solutions n'ont pas fonctionné pour mon code.

Cependant, j'ai trouvé une solution. Peut-être que cette solution aide d’autres codeurs qui ont un problème comme le mien.

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");

Cette solution fonctionne pour 8 bits 256 bpp (Format8bppIndexed). Si votre image a un autre format, vous devriez changer PixelFormat.

Et il y a un problème de couleurs en ce moment. Dès que j'aurai résolu celui-ci, je modifierai ma réponse pour les autres utilisateurs.

* PS = Je ne suis pas sûr de la valeur de stride, mais pour 8 bits, cela devrait être égal à des colonnes.

Et aussi cette fonction fonctionne pour moi .. Cette fonction copie une image en niveaux de gris 8 bits dans une mise en page 32 bits.

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"));
                    }
                }
            }
        }
22
goGud

Vous aurez besoin d'obtenir ces bytes dans un MemoryStream:

Bitmap bmp;
using (var ms = new MemoryStream(imageData))
{
    bmp = new Bitmap(ms);
}

Cela utilise la surcharge du constructeur Bitmap(Stream stream) .

UPDATE: N'oubliez pas que, selon la documentation et le code source que j'ai lus, un ArgumentException sera lancé. à ces conditions:

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.
96
Mike Perrenoud

Peut être aussi simple que:

var ms = new MemoryStream(imageData);
System.Drawing.Image image = Image.FromStream(ms);

image.Save("c:\\image.jpg");

Le tester:

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");
}
15
Mario Sannum