当前位置:编程学习 > C/C++ >>

C++图像处理 -- PCX格式图像(下)

本文则介绍将GDI+位图转换为PCX格式图像。
 
    下面是GDI+位图转换为PCX格式图像代码:
 
[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 && count < 0x3f);  
        if (c >= 0xc0 || count > 1)  
            *pd ++ = count | 0xc0;  
        *pd ++ = c;  
    }  
    return pd - dest;  
}  
//---------------------------------------------------------------------------   
  
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);  
}  
//---------------------------------------------------------------------------   
  
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 *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];  
        // 如果是16色位图,调色板保存到文件头   
        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;  
    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)  
        hea
补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,