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?
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);
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);
}
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];
}
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");
}
}