This article describes how to convert a GDI + bitmap to a PCX image. The following is the code for converting a GDI + bitmap to a PCX Format Image: [cpp] INT PackPcxLine (LPBYTE dest, LPBYTE source, INT bytesPreLine, INT planes) {LPBYTE pd = dest; INT delta = planes --; LPBYTE ps = source + planes; INT bytes = bytesPreLine; while (planes> = 0) {INT count = 0; BYTE c = * ps; do {count ++; if (-- bytes = 0) {if (-- planes <0) break; bytes = bytesPreLine; ps = source + planes ;} else ps + = delta;} while (c = * ps & cou Nt <0x3f); if (c> = 0xc0 | count> 1) * pd ++ = count | 0xc0; * pd ++ = c;} return pd-dest ;} // define typedef union {WORD value; struct {BYTE low; BYTE high ;};} testMask; INT PackPcx4Line (LPBYTE dest, LPBYTE source, INT bytesPreLine, INT width) {INT bytes = bytesPreLine <2; LPBYTE buf = dest + bytes; testMask mask; mask. Value = 0x1001; width = (width + 1)> 1; while (mask. high) {BYTE c = 0; BYTE bit = 0x80; LPBYTE pb = buf; for (INT I = 0; I <width; I ++) {if (source [I] & mask. high) c | = bit; bit >>=1; if (source [I] & mask. low) c | = bit; bit >>=1; if (bit = 0) {* pb ++ = c; c = 0; bit = 0x80 ;}} buf + = bytesPreLine; mask. value <= 1;} return PackPcxLine (dest, dest + bytes, bytes, 1 );}//---------------- Protected VOID ARGBQuadToRGBTriple (PRGBTriple dest, PRGBQuad source, INT count) {for (INT I = 0; I <count; I ++) {dest [I]. rgbtBlue = source [I]. rgbRed; dest [I]. rgbtGreen = source [I]. rgbGreen; dest [I]. rgbtRed = source [I]. rgbBlue; }}// ------------------------------------------------------------------------------- BOOL SavePcxImageToStream (IStream * str Eam, Bitmap * bmp) {PixelFormat format = bmp-> GetPixelFormat (); if (format = PixelFormatUndefined) return FALSE; PcxFileHeader header; ColorPalette * pal = NULL; BYTE palate [256*3 + 1]; ZeroMemory (& header, sizeof (PcxFileHeader); header. bitsPrePixel = GetPixelFormatSize (format); header. planes = 1; if (header. bitsPrePixel> 8) {format = PixelFormat24bppRGB; header. planes = 3; header. bitsPrePixe L = 8;} else // if (header. bitsPrePixel> 1) {pal = (ColorPalette *) new BYTE [256 * sizeof (ARGB) + sizeof (ColorPalette)]; bmp-> GetPalette (pal, bmp-> GetPaletteSize (); PRGBTriple ppal = (PRGBTriple) & palette [1]; // if it is a 16-color bitmap, the color palette is saved to the file header if (format = PixelFormat4bppIndexed) {header. planes = header. bitsPrePixel; header. bitsPrePixel = 1; ppal = (PRGBTriple) header. palette;} ARGBQuadToRGBTriple (ppal, (PRG BQuad) pal-> Entries, pal-> Count); delete [] pal;} Gdiplus: Rect r (0, 0, bmp-> GetWidth (), bmp-> GetHeight (); header. flag = 0x0A; header. version = 5; header. encodeing = 1; header. xMax = r. width-1; header. yMax = r. height-1; header. hRes = 96; header. vRes = 96; header. paletteType = 1; header. bytesPreLine = (r. width * header. bitsPrePixel + 7)> 3; if (header. bytesPreLine & 1) header. bytesPreLine ++; // Save the PCX File header if (stream-> Write (& header, sizeof (PcxFileHeader), NULL )! = S_ OK) return FALSE; // obtain the GDI + bitmap data in place graph data structure BitmapData data; data. stride = (r. width * GetPixelFormatSize (format) + 31) &-32)> 3; INT size = r. height * data. stride; // size is the number of bytes of bitmap data, header. bytesPreLine * header. planes * 2 is the number of bytes in the encoding buffer. scan0 = (LPVOID) new BYTE [size + header. bytesPreLine * header. planes * 2]; bmp-> LockBits (& r, ImageLockModeRead | ImageLockModeUserInputBuf, format, & data); bmp-> UnlockBi Ts (& data); // if the first item of the monochrome bitmap palette is not 0, the bitmap data is reversed if (format = PixelFormat1bppIndexed & (* (ARGB *) & palette [1] & 0 xffffff) {INT count = data. height * (data. stride> 2); LPDWORD pd = (LPDWORD) data. scan0; for (INT I = 0; I <count; pd [I] ^ = (DWORD) (-1), I ++);} LPBYTE p = (LPBYTE) data. scan0; LPBYTE buffer = p + size; INT bytes; // encode RLE row by row and save it to the stream for (UINT y = 0; y <data. height; y ++, p + = data. stride) {if (Format = PixelFormat4bppIndexed) bytes = PackPcx4Line (buffer, p, header. bytesPreLine, data. width); else bytes = PackPcxLine (buffer, p, header. bytesPreLine, header. planes); stream-> Write (buffer, bytes, NULL);} delete [] data. scan0; // if it is a 256-color bitmap, the color palette is saved to the end of the stream if (format = PixelFormat8bppIndexed) {palette [0] = 0x0c; stream-> Write (palette, 256*3 + 1, NULL);} return TRUE ;}//----------------------- Required BOOL SavePcxImageToFile (LPTSTR fileName, Bitmap * bmp) {IStream * stream = new FileStream (fileName, FALSE); stream-> AddRef (); BOOL result = SavePcxImageToStream (stream, bmp); stream-> Release (); return result;} // optional INT PackPcxLine (LPBYTE dest, LPBYTE source, INT bytesPreLin E, INT planes) {LPBYTE pd = dest; INT delta = planes --; LPBYTE ps = source + planes; INT bytes = bytesPreLine; while (planes> = 0) {INT count = 0; BYTE c = * ps; do {count ++; if (-- bytes = 0) {if (-- planes <0) break; bytes = bytesPreLine; ps = source + planes;} else ps + = delta;} while (c = * ps & count <0x3f); if (c> = 0xc0 | count> 1) * pd ++ = count | 0xc0; * pd ++ = c;} return pd-dest ;}//---------------- Revoke typedef union {WORD value; struct {BYTE low; BYTE high ;};} testMask; INT PackPcx4Line (LPBYTE dest, LPBYTE source, INT bytesPreLine, INT width) {INT bytes = bytesPreLine <2; LPBYTE buf = dest + bytes; testMask mask; mask. value = 0x1001; width = (width + 1)> 1; while (mask. high) {BYTE c = 0; BYTE bit = 0x80; LPBYTE pb = buf; for (INT I = 0; I <width; I ++) {if (source [I] & mask. high) c | = bit; bit >>=1; if (source [I] & mask. low) c | = bit; bit >>=1; if (bit = 0) {* pb ++ = c; c = 0; bit = 0x80 ;}} buf + = bytesPreLine; mask. value <= 1;} return PackPcxLine (dest, dest + bytes, bytes, 1);} // define VOID ARGBQuadToRGBTriple (PRGBTriple dest, PRGBQuad source, INT count) {for (INT I = 0; I <co Unt; I ++) {dest [I]. rgbtBlue = source [I]. rgbRed; dest [I]. rgbtGreen = source [I]. rgbGreen; dest [I]. rgbtRed = source [I]. rgbBlue ;}}// your BOOL SavePcxImageToStream (IStream * stream, Bitmap * bmp) {PixelFormat format = bmp-> GetPixelFormat (); if (format = PixelFormatUndefined) return FALSE; pcxFileHeader header; ColorPalette * pal = NULL; BYTE Palette [256*3 + 1]; ZeroMemory (& header, sizeof (PcxFileHeader); header. bitsPrePixel = GetPixelFormatSize (format); header. planes = 1; if (header. bitsPrePixel> 8) {format = PixelFormat24bppRGB; header. planes = 3; header. bitsPrePixel = 8;} else // if (header. bitsPrePixel> 1) {pal = (ColorPalette *) new BYTE [256 * sizeof (ARGB) + sizeof (ColorPalette)]; bmp-> GetPalette (pal, bmp-> GetPaletteSize (); PRGBTriple ppal = (PRGBTriple) & palette [1]; // if it is a 16-color bitmap, save the color palette to the file header if (format = PixelFormat4bppIndexed) {header. planes = header. bitsPrePixel; header. bitsPrePixel = 1; ppal = (PRGBTriple) header. palette;} ARGBQuadToRGBTriple (ppal, (PRGBQuad) pal-> Entries, pal-> Count); delete [] pal;} Gdiplus: Rect r (0, 0, bmp-> GetWidth (), bmp-> GetHeight (); header. flag = 0x0A; header. version = 5; header. encodeing = 1; header. xMax = r. width-1; h Eader. yMax = r. height-1; header. hRes = 96; header. vRes = 96; header. paletteType = 1; header. bytesPreLine = (r. width * header. bitsPrePixel + 7)> 3; if (header. bytesPreLine & 1) header. bytesPreLine ++; // Save the PCX File header if (stream-> Write (& header, sizeof (PcxFileHeader), NULL )! = S_ OK) return FALSE; // obtain the GDI + bitmap data in place graph data structure BitmapData data; data. stride = (r. width * GetPixelFormatSize (format) + 31) &-32)> 3; INT size = r. height * data. stride; // size is the number of bytes of bitmap data, header. bytesPreLine * header. planes * 2 is the number of bytes in the encoding buffer. scan0 = (LPVOID) new BYTE [size + header. bytesPreLine * header. planes * 2]; bmp-> LockBits (& r, ImageLockModeRead | ImageLockModeUserInputBuf, format, & data); bmp-> UnlockBits (& data); // If the first item of the monochrome bitmap palette is not 0, the bitmap data is reversed if (format = PixelFormat1bppIndexed & (* (ARGB *) & palette [1] & 0 xffffff )) {INT count = data. height * (data. stride> 2); LPDWORD pd = (LPDWORD) data. scan0; for (INT I = 0; I <count; pd [I] ^ = (DWORD) (-1), I ++);} LPBYTE p = (LPBYTE) data. scan0; LPBYTE buffer = p + size; INT bytes; // encode RLE row by row and save it to the stream for (UINT y = 0; y <data. height; y ++, p + = data. stride) {if (format = PixelFormat4b PpIndexed) bytes = PackPcx4Line (buffer, p, header. bytesPreLine, data. width); elsebytes = PackPcxLine (buffer, p, header. bytesPreLine, header. planes); stream-> Write (buffer, bytes, NULL);} delete [] data. scan0; // if it is a 256-color bitmap, the color palette is saved to the end of the stream if (format = PixelFormat8bppIndexed) {palette [0] = 0x0c; stream-> Write (palette, 256*3 + 1, NULL);} return TRUE ;}//------------------------------------------------------------- -------------- BOOL SavePcxImageToFile (LPTSTR fileName, Bitmap * bmp) {IStream * stream = new FileStream (fileName, FALSE); stream-> AddRef (); BOOL result = SavePcxImageToStream (stream, bmp); stream-> Release (); return result;} // in the extract code, the SavePcxImageToStream function has commented on the approximate conversion process, the SavePcxImageToFile function still uses the simple file stream I wrote to save the converted PCX format image to the file. Below is a G Format: [cpp] void _ fastcall TForm1: Button3Click (TObject * Sender) {Gdiplus: Bitmap * bmp = new Gdiplus:: Bitmap (L "d: \ 1-4.bmp"); if (bmp-> GetLastStatus ()! = OK) throw new Exception ("Load Image fail"); Gdiplus: Graphics * g = new Gdiplus: Graphics (Canvas-> Handle); g-> DrawImage (bmp, 0, 0); delete g; SavePcxImageToFile ("d: \ 1-4.pcx", bmp); delete bmp ;}