Quel est le but de ImageLockMode dans Bitmap.LockBits? Pour ReadOnly le documentation que seuls les EtatsBut de ImageLockMode dans Bitmap.LockBits (avec du code)
ReadOnly: Indique qu'une partie de l'image est verrouillée pour la lecture.
Mais le code suivant prouve que cela n'est pas vrai. Je sais que la question a déjà été posée, cette fois-ci j'essaie avec un code réel car je ne trouve pas de réponse ailleurs.
Si je cours le code suivant, il se comporte exactement comme expliqué dans la réponse.
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace LockBits_Trials
{
class Program
{
static readonly Random rnd = new Random(42);
static void Main(string[] args)
{
Bitmap bmp_fromFile = new Bitmap("example.png");
Bitmap bmp_fromCtor = new Bitmap(100, 100, PixelFormat.Format24bppRgb);
marshalCopy(bmp_fromFile, "result_marshalCopy_fromFile.png");
marshalCopy(bmp_fromCtor, "result_marshalCopy_fromCtor.png");
usePointer(bmp_fromFile, "result_usePointer_fromFile.png");
usePointer(bmp_fromCtor, "result_usePointer_fromCtor.png");
}
private static unsafe void usePointer(Bitmap bmp, string filename)
{
ImageLockMode mode = ImageLockMode.ReadOnly;
//code from turgay at http://csharpexamples.com/fast-image-processing-c/
if (bmp.PixelFormat != PixelFormat.Format24bppRgb)
throw new Exception();
BitmapData bitmapData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), mode, bmp.PixelFormat);
int bytesPerPixel = 3; int heightInPixels = bitmapData.Height; int widthInBytes = bitmapData.Width * bytesPerPixel;
byte* ptrFirstPixel = (byte*)bitmapData.Scan0;
for (int y = 0; y < heightInPixels; y++) {
byte* currentLine = ptrFirstPixel + (y * bitmapData.Stride);
for (int x = 0; x < widthInBytes; x = x + bytesPerPixel) {
currentLine[x] = (byte)rnd.Next(0, 255);
currentLine[x + 1] = (byte)rnd.Next(0, 255);
currentLine[x + 2] = (byte)rnd.Next(0, 255);
}
}
bmp.UnlockBits(bitmapData);
bmp.Save(filename, ImageFormat.Png);
}
private static unsafe void marshalCopy(Bitmap bmp, string filename)
{
ImageLockMode mode = ImageLockMode.ReadOnly;
if (bmp.PixelFormat != PixelFormat.Format24bppRgb)
throw new Exception();
BitmapData bitmapData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), mode, bmp.PixelFormat);
IntPtr ptrFirstPixel = bitmapData.Scan0;
int totalBytes = bitmapData.Stride * bitmapData.Height;
byte[] newData = new byte[totalBytes];
for (int i = 0; i < totalBytes; i++)
newData[i] = (byte)rnd.Next(0, 255);
Marshal.Copy(newData, 0, ptrFirstPixel, newData.Length);
bmp.UnlockBits(bitmapData);
bmp.Save(filename, ImageFormat.Png);
}
}
}
Les images result_marshalCopy_fromFile.png et result_usePointer_fromFile.png contiennent tous deux l'image d'origine, donc rien a été écrasé (et pas exception levée!). Les deux autres images contiennent le bruit aléatoire qui leur a été écrit pendant leur verrouillage.
Je n'ai pas effectué de test supplémentaire pour confirmer le comportement de l'accès en écriture parallèle, car je ne le fais pas de toute façon.
Ce n'est pas un double, mais fortement liée: Does Bitmap.LockBits “pin” a bitmap into memory?
Vous n'êtes pas assez difficile, pas de codec pour rester heureux. Vous devrez rendre sa vie plus difficile en demandant intentionnellement un format de pixel qui ne correspond pas au format de pixel de l'image bitmap. –
@Hans Passant Je ne comprends pas? –