Specific process is:
1) through the System. The Runtime. InteropServices. Marshal. AllocHGlobal (int cb) define an intptr
2) related data into the memory space of intptr
3) use new Bitmap (Int32, Int32, Int32, PixelFormat, IntPtr) IntPtr can be converted to Bitmap image
Have a problem at this time, if the call System. Runtime. InteropServices. Marshal. FreeHGlobal (System. IntPtr) release the memory, IntPtr new bitmap image is damaged, if you don't release the memory IntPtr, System memory crazy be eaten
The code is as follows:
Public static void ColortoGray (ref Bitmap ImageScr, ref Bitmap ImageDst)
{
Int height=ImageScr. Height;
Int width=ImageScr. Width;
Int offsetDst=width/4 * 4 + 4 - width;
If (offsetDst==4)
OffsetDst=0;
Int strideDst=width + offsetDst;
Int num=strideDst * height;
IntPtr intptrbuffer=System. The Runtime. InteropServices. Marshal. AllocHGlobal (num);
BitmapData dataScr=ImageScr. LockBits (new Rectangle (0, 0, width, height), ImageLockMode. ReadOnly, ImageScr. PixelFormat);
Int offsetScr=dataScr. Stride - width * 3;
The unsafe
{
Byte * ptrScr=(byte *) dataScr Scan0. ToPointer ();
Byte * ptrDst=(byte *) intptrbuffer ToPointer ();
for (int i=0; i
For (int j=0; J & lt; Width; J++)
{
* ptrDst=(byte) (+ 0.587 * 0.114 * ptrScr (*) (* (ptrScr + 1)) + 0.299 * (* (ptrScr + 2)));
PtrDst++;
PtrScr +=3;
}
PtrDst +=offsetDst;
PtrScr +=offsetScr;
}
}
ImageScr. UnlockBits (dataScr);
If (ImageDst!=null)
{
ImageDst. The Dispose ();//release image resources
}
ImageDst=new Bitmap (width, height, strideDst PixelFormat. Format8bppIndexed, intptrbuffer);
//System. The Runtime. InteropServices. Marshal. FreeHGlobal (intptrbuffer);//release intptrbuffer memory,
//set the palette
ColorPalette palette=ImageDst. The palette;
for (int i=0; i
ImageDst. The Palette=the Palette;
}
Personal understanding new bitmap image should put intptr occupied, but repeated calls to the segment code, since ImageDst is created through the last time this function is called intptr images, but through ImageDst. The Dispose () image resources, intptr memory did not release
Actually defines a byte [] buffer=new byte (num) instead of intptr as interim cache is also no problem, but the appearance of the poor performance by almost 20%, individual curious is that through the form of intptr how to implement this functionality in c #, after all, a lot of poor performance
CodePudding user response:
If the gray image is used to display, need not trouble index color (according to internal and conversion back), may also will be quicker,public static Bitmap ToGrayscale Bitmap (SRC)
{
Var DST=new Bitmap (SRC, Width, SRC. Height);
Using (var g=Graphics. FromImage (DST))
{
Var ias=new ImageAttributes ();
Var m=new ColorMatrix ();
M (0, 0)=m=[0, 1] m [0, 2)=0.299 f;
M (1, 0] [1, 1)=m=m=0.587 f [1, 2];
M (2, 0)=m (2, 1] [2, 2]=m=0.114 f;
Ias. SetColorMatrix (m);
G.D rawImage (SRC, new Rectangle (Point. The Empty, SRC. The Size), 0, 0, SRC, Width, SRC, Height, GraphicsUnit. The Pixel, ias);
}
return dst;
}