Comment accéder à chaque octet dans une image bitmap

si j'ai une image bitmap, est-il possible d'itérer tous les octets de l'image? Si oui, comment?

3
demandé sur Blankman 2008-12-03 18:58:53

4 réponses

j'ai trouvé ça: http://channel9.msdn.com/forums/TechOff/108813-Bitmap-to-byte-array /

disant que vous pourriez utiliser un flux de souvenirs et le .Méthode de sauvegarde il semblerait comme ceci:

System.Drawing.Bitmap bmp = GetTheBitmap();
System.IO.MemoryStream stream = new System.IO.MemoryStream();
bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);
stream.Position = 0;
byte[] data = new byte[stream.Length];
stream.Read(data, 0, stream.Length);
6
répondu Filip Ekberg 2008-12-03 16:03:05

utilise le membre LockBits sur la classe Bitmap pour obtenir BitmapData, puis utilise Scan0 et Marshal.ReadByte à readbytes. Voici un petit exemple (il ne s'agit pas du réglage correct de la luminosité, cependant):

    public static void AdjustBrightness(Bitmap image, int brightness)
    {
        int offset = 0;
        brightness = (brightness * 255) / 100;
        // GDI+ still lies to us - the return format is BGR, NOT RGB.
        BitmapData bmData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

        int stride = bmData.Stride;
        IntPtr Scan0 = bmData.Scan0;

        int nVal = 0;
        int nOffset = stride - image.Width * 3;
        int nWidth = image.Width * 3;

        for (int y = 0; y < image.Height; ++y)
        {
            for (int x = 0; x < nWidth; ++x)
            {
                nVal = Marshal.ReadByte(Scan0, offset) + brightness;

                if (nVal < 0)
                    nVal = 0;
                if (nVal > 255)
                    nVal = 255;

                Marshal.WriteByte(Scan0, offset, (byte)nVal);
                ++offset;
            }
            offset += nOffset;
        }
        image.UnlockBits(bmData);
    }
4
répondu Ilya Ryzhenkov 2008-12-03 16:08:26

si vous avez besoin d'accéder aux informations du pixel, le moyen super-lent mais super-facile est d'appeler les méthodes GetPixel et SetPixel sur votre objet Bitmap.

le moyen le plus rapide et le plus simple est d'appeler la méthode LockBits de Bitmap et d'utiliser L'objet BitmapData retourné pour lire et écrire directement les données octets de Bitmap. Vous pouvez faire cette dernière partie avec la classe Marshal comme dans L'exemple D'Ilya, ou vous pouvez sauter la tête Marshal comme ceci:

    BitmapData data;
    int x = 0; //or whatever
    int y = 0;
    unsafe
    {
        byte* row = (byte*)data.Scan0 + (y * data.Stride);
        int columnOffset = x * 4;
        byte B = row[columnOffset];
        byte G = row[columnOffset + 1];
        byte R = row[columnOffset + 2];
        byte A = row[columnOffset + 3];
    }
4
répondu MusiGenesis 2008-12-03 16:51:23

une autre solution consiste à utiliser des LockBits et des Marshals.Copiez pour convertir votre bitmap en tableau. J'avais besoin de cette solution parce que j'avais deux images qui différaient seulement dans leur profondeur de couleur et les autres solutions proposées ne gèrent pas bien (ou sont trop lents).

using (Bitmap bmp = new Bitmap(fname)) {
    // Convert image to int32 array with each int being one pixel
    int cnt = bmp.Width * bmp.Height * 4 / 4;
    BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
                            ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
    Int32[] rgbValues = new Int32[cnt];

    // Copy the RGB values into the array.
    System.Runtime.InteropServices.Marshal.Copy(bmData.Scan0, rgbValues, 0, cnt);
    bmp.UnlockBits(bmData);
    for (int i = 0; i < cnt; ++i) {
        if (rgbValues[i] == 0xFFFF0000)
            Console.WriteLine ("Red byte");
    }
}
0
répondu Keith 2009-05-11 17:40:55