int width = bitmap.Width;
int height = bitmap.Height;
Bitmap bitmap1Bit = new Bitmap(width, height, PixelFormat.Format1bppIndexed);
//le pattern a appliquer sur des niveaux de gris de 64
byte[][] pattern = new byte[][]{ new byte[]{0,32,8,40,34,2,10,42},
new byte[]{48,16,56,24,50,18,58,26},
new byte[]{12,44,4,36,14,46,6,38},
new byte[]{60,28,52,20,62,30,54,22},
new byte[]{3,35,11,43,1,33,9,41},
new byte[]{51,19,59,27,49,17,57,25},
new byte[]{15,47,7,39,13,45,5,37},
new byte[]{63,31,55,23,61,29,53,21}};
//tables de precalculs des multiplications pour le calcul du niveau de gris
int[] multiBleu = new int[256];
int[] multiVert = new int[256];
int[] multiRouge = new int[256];
for (int i = 0; i < 256; i++)
{
multiBleu[i] = 76 * i;
multiVert[i] = 151 * i;
multiRouge[i] = 28 * i;
}
unsafe
BitmapData bmpDataOld = bitmap.LockBits(new Rectangle(0,
0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
BitmapData bmpDataNew = bitmap1Bit.LockBits(new Rectangle(0, 0,
width, height), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed);
byte* oldPixel = (byte*)(void*)bmpDataOld.Scan0;
byte* newPixel = (byte*)(void*)bmpDataNew.Scan0;
//l'offset de l'image 1 bit
int offset = bmpDataNew.Stride - (width / 8);
byte pixel;//Niveau de gris
int newPix = 0;//ensemble de 8 pixels
for (int y = 0; y < height; y++)
for (int x = 1; x <= width; x++)
//A partir des composantes du pixel
//de l'image 32 bits, on determine
//le niveau de gris
pixel = (byte)((multiBleu[oldPixel[0]] + multiVert[oldPixel[1]]
+ multiRouge[oldPixel[2]]) >> 8);
//on compare le pixel (reduit 64 niveaux)
//au pattern (en fonction de sa position
//par rapport l'image)
if ((pixel >> 2) > pattern[x & 7][y & 7])
//on allume le pixel (Bit=1)
//dans le byte
newPix = newPix | (1 << (7 - (x % 8)));
if (x % 8 == 0)
//quand on a rempli 8 bits
//on ecrit le byte dans l'image
newPixel[0] = (byte)newPix;
//on avance le pointeur
newPixel++;
//on teint tous les pixels
//pour le nouveau cycle de 8 bits
newPix = 0;
oldPixel += 4;
newPixel += offset;
bitmap.UnlockBits(bmpDataOld);
bitmap1Bit.UnlockBits(bmpDataNew);
static byte[][] TabloImbriques()
byte[][] tab = new byte [16][];
tab[0][0] = 1;
return tab;
.method private hidebysig static uint8[][]
TabloImbriques() cil managed
// Code size 21 (0x15)
.maxstack 3
.locals init ([0] uint8[][] tab,
[1] uint8[][] CS$1$0000)
IL_0000: nop
IL_0001: ldc.i4.s 16
IL_0003: newarr uint8[]
IL_0008: stloc.0
IL_0009: ldloc.0
IL_000a: ldc.i4.0
IL_000b: ldelem.ref
IL_000c: ldc.i4.0
IL_000d: ldc.i4.1
IL_000e: stelem.i1
IL_000f: ldloc.0
IL_0010: stloc.1
IL_0011: br.s IL_0013
IL_0013: ldloc.1
IL_0014: ret
} // end of method Program::TabloImbriques
static byte[,] TabloMultiDimensions()
byte[,] tab = new byte[16,16];
tab[0, 0] = 1;
.method private hidebysig static uint8[0...,0...]
TabloMultiDimensions() cil managed
// Code size 26 (0x1a)
.maxstack 4
.locals init ([0] uint8[0...,0...] tab,
[1] uint8[0...,0...] CS$1$0000)
IL_0003: ldc.i4.s 16
IL_0005: newobj instance void uint8[0...,0...]::.ctor(int32,
int32)
IL_000a: stloc.0
IL_000b: ldloc.0
IL_000d: ldc.i4.0
IL_000e: ldc.i4.1
IL_000f: call instance void uint8[0...,0...]::Set(int32,
int32,
uint8)
IL_0014: ldloc.0
IL_0015: stloc.1
IL_0016: br.s IL_0018
IL_0018: ldloc.1
IL_0019: ret
} // end of method Program::TabloMultiDimensions
byte[] pattern = new byte[64]{0,32,8,40,34,2,10,42,
48,16,56,24,50,18,58,26,
12,44,4,36,14,46,6,38,
60,28,52,20,62,30,54,22,
3,35,11,43,1,33,9,41,
51,19,59,27,49,17,57,25,
15,47,7,39,13,45,5,37,
63,31,55,23,61,29,53,21};
if ((pixel >> 2) > pattern[(x & 7) * 8 + (y & 7)])
//Au lieu de :
//if ((pixel >> 2) > pattern[x & 7][y & 7])
static int Multiplie(int x)
return x * 8;
static int Decale(int x)
return x << 3;
00000026 8B C7 mov eax,edi
00000028 C1 E0 03 shl eax,3
0000002b 8B F0 mov esi,eax