Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在.net compact framework中将图像转换为1 bpp位图_C#_Windows Mobile_Compact Framework_Bitmap - Fatal编程技术网

C# 在.net compact framework中将图像转换为1 bpp位图

C# 在.net compact framework中将图像转换为1 bpp位图,c#,windows-mobile,compact-framework,bitmap,C#,Windows Mobile,Compact Framework,Bitmap,我有一个签名的图像,我正试图保存为1 bpp位图以节省文件空间。完整的.NET Framework具有enumPixelFormat.Format1BPindexed,但.NET Compact Framework不支持它 有人在Windows Mobile中发现了实现这一点的方法吗?即使在完整的框架中,创建和保存双音位图也是有问题的 我以前写过一篇关于这个问题的文章 我在compact框架的上下文中重温了这段代码,并发现正如您所做的那样,枚举值不存在,因此您无法从头创建双音图像 我想知道你是

我有一个签名的图像,我正试图保存为1 bpp位图以节省文件空间。完整的.NET Framework具有enum
PixelFormat.Format1BPindexed
,但.NET Compact Framework不支持它


有人在Windows Mobile中发现了实现这一点的方法吗?

即使在完整的框架中,创建和保存双音位图也是有问题的

我以前写过一篇关于这个问题的文章

我在compact框架的上下文中重温了这段代码,并发现正如您所做的那样,枚举值不存在,因此您无法从头创建双音图像


我想知道你是否可以在紧凑的框架中加载预先存在的双音图像。如果您可以加载预先存在的位图,那么可能可以降低级别,直接将位图图像格式写入磁盘或内存流,而不是使用GDI+对象,但这样做并不简单。

我过去必须这样做才能生成通过蓝牙打印的黑白报告(彩色或灰度图像对于打印机的缓冲区来说太大了)。结果我不得不使用本机代码创建图像

下面是一个片段:

private void CreateUnmanagedResources()
{
    // for safety, clean up anything that was already allocated
    ReleaseUnmanagedResources();

    bih = new BITMAPINFOHEADER();
    bih.biBitCount = 1;
    bih.biClrImportant = 0;
    bih.biClrUsed = 0;
    bih.biCompression = 0;
    bih.biHeight = m_cy;
    bih.biPlanes = 1;
    bih.biSize = (uint)(Marshal.SizeOf(typeof(BITMAPINFOHEADER)) - 8); 
    bih.biSizeImage = 0;
    bih.biWidth = m_cx;
    bih.biXPelsPerMeter = 0;
    bih.biYPelsPerMeter = 0;
    bih.clr2 = 0xffffff;
    bih.clr1 = 0x0;

    hDC = Win32.CreateCompatibleDC(IntPtr.Zero);
    pBits = IntPtr.Zero;
    hBitmap = Win32.CreateDIBSection(hDC, bih, 1, ref pBits, IntPtr.Zero, 0);
    hbmOld = Win32.SelectObject(hDC, hBitmap);
}

private void ReleaseUnmanagedResources()
{
    if (hbmOld != IntPtr.Zero)
        Win32.SelectObject(hDC, hbmOld);

    if(hBitmap != IntPtr.Zero)
        Win32.DeleteObject(hBitmap);

    if (hDC != IntPtr.Zero)
        Win32.DeleteDC(hDC);
}
然后,我使用Graphics.FromHdc获得了一个托管图形对象,我可以在该对象上绘制报告


我使用BinaryWriter进行了保存,但那是在CF 1.0的日子里,Bitmap类没有保存,所以您在那里是自由的。

感谢您为我指明了正确的方向。 我无法使用
Bitmap
类保存图像数据。它不断抛出
OutOfMemoryException
。正如您所建议的,我使用BinaryWriter写入位图

我的最终解决方案返回一个字节数组,您可以使用它选择写入磁盘、保存到数据库、传输等

class ImageHelper
{
    [StructLayout(LayoutKind.Sequential)]
    public struct BITMAPINFOHEADER
    {
        public BITMAPINFOHEADER(ushort bpp, int height, int width)
        {
            biBitCount = bpp;
            biWidth = width;
            biHeight = height;

            biSize = (uint)Marshal.SizeOf(typeof(BITMAPINFOHEADER));
            biPlanes = 1; // must be 1
            biCompression = 0; // no compression
            biSizeImage = 0; // no compression, so can be 0
            biXPelsPerMeter = 0;
            biYPelsPerMeter = 0;
            biClrUsed = 0;
            biClrImportant = 0;
        }

        public void Store(BinaryWriter bw)
        {
            Store(bw, null);
        }

        public void Store(BinaryWriter bw, uint[] colorPalette)
        {
            // Must maintain order for file writing
            bw.Write(biSize);
            bw.Write(biWidth);
            bw.Write(biHeight);
            bw.Write(biPlanes);
            bw.Write(biBitCount);
            bw.Write(biCompression);
            bw.Write(biSizeImage);
            bw.Write(biXPelsPerMeter);
            bw.Write(biYPelsPerMeter);
            bw.Write(biClrUsed);
            bw.Write(biClrImportant);

            // write color palette if 8 bpp or less
            if (biBitCount <= 8)
            {
                if (colorPalette == null)
                    throw new ArgumentNullException("bpp is 8 or less, color palette is required");

                uint paletteCount = BITMAPFILEHEADER.CalcPaletteSize(biBitCount) / 4;
                if (colorPalette.Length < paletteCount)
                    throw new ArgumentException(string.Format("bpp is 8 or less, color palette must contain {0} colors", paletteCount));

                foreach (uint color in colorPalette)
                    bw.Write(color);
            }
        }

        public uint biSize;
        public int biWidth;
        public int biHeight;
        public ushort biPlanes;
        public ushort biBitCount;
        public uint biCompression;
        public uint biSizeImage;
        public int biXPelsPerMeter;
        public int biYPelsPerMeter;
        public uint biClrUsed;
        public uint biClrImportant;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct BITMAPFILEHEADER
    {
        public BITMAPFILEHEADER(BITMAPINFOHEADER info, out uint sizeOfImageData)
        {
            bfType = 0x4D42;  // Microsoft supplied value to indicate Bitmap 'BM'
            bfReserved1 = 0;
            bfReserved2 = 0;

            // calculate amount of space needed for color palette
            uint paletteSize = CalcPaletteSize(info.biBitCount);

            bfOffBits = 54 + paletteSize; // default value + paletteSize

            // calculate size of image
            sizeOfImageData = (uint)(CalcRowSize(info.biWidth * info.biBitCount) * info.biHeight);
            bfSize = sizeOfImageData + bfOffBits;
        }

        private static int CalcRowSize(int bits)
        {
            return ((((bits) + 31) / 32) * 4);
        }

        public static uint CalcPaletteSize(int bpp)
        {
            // 8 bpp or less, needs an uint per color
            if (bpp <= 8)
                return 4 * (uint)Math.Pow(2, bpp);

            // no palette needed for 16bpp or higher
            return 0;
        }

        public void Store(BinaryWriter bw)
        {
            // Must maintain order for file writing
            bw.Write(bfType);
            bw.Write(bfSize);
            bw.Write(bfReserved1);
            bw.Write(bfReserved2);
            bw.Write(bfOffBits);
        }

        public ushort bfType;
        public uint bfSize;
        public short bfReserved1;
        public short bfReserved2;
        public uint bfOffBits;
    }

    public static byte[] GetByteArray(Bitmap image)
    {
        IntPtr hbmOld;
        IntPtr hBitmap;
        IntPtr hDC;

        // create infoheader
        BITMAPINFOHEADER bih = new BITMAPINFOHEADER(1, image.Height, image.Width);
        // set black and white for 1 bit color palette

        // create fileheader and get data size
        uint sizeOfImageData;
        BITMAPFILEHEADER bfh = new BITMAPFILEHEADER(bih, out sizeOfImageData);

        // create device context in memory
        hDC = Win32.CreateCompatibleDC(IntPtr.Zero);

        // create a 1 bpp DIB
        IntPtr pBits = IntPtr.Zero;
        hBitmap = Win32.CreateDIBSection(hDC, ref bih, 1, ref pBits, IntPtr.Zero, 0);

        // selet DIB into device context
        hbmOld = Win32.SelectObject(hDC, hBitmap);

        using (Graphics g = Graphics.FromHdc(hDC))
        {
             g.DrawImage(image, 0, 0);
        }

        byte[] imageData = new byte[sizeOfImageData];
        byte[] fileData;

        using (MemoryStream ms = new MemoryStream((int)bfh.bfSize))
        {
            using (BinaryWriter w = new BinaryWriter(ms))
            {
                bfh.Store(w);
                // store bitmapinfoheader with 1 bpp color palette for black and white
                bih.Store(w, new uint[] { (uint)0x0, (uint)0xffffff });

                // copy image data into imageData buffer
                Marshal.Copy(pBits, imageData, 0, imageData.Length);

                // write imageData to stream
                w.Write(imageData);

                w.Close();
            }

            fileData = ms.GetBuffer();
            ms.Close();
        }

        // select old object
        if (hbmOld != IntPtr.Zero)
            Win32.SelectObject(hDC, hbmOld);

        // delete memory bitmap
        if (hBitmap != IntPtr.Zero)
            Win32.DeleteObject(hBitmap);

        // delete memory device context
        if (hDC != IntPtr.Zero)
            Win32.DeleteDC(hDC);

        return fileData;
    }
}
类ImageHelper
{
[StructLayout(LayoutKind.Sequential)]
公共结构BitMapInfo标头
{
公共位图信息头(ushort bpp、整型高度、整型宽度)
{
biBitCount=bpp;
宽度=宽度;
高度=高度;
biSize=(uint)Marshal.SizeOf(typeof(BitMapInfo头));
双平面=1;//必须为1
biCompression=0;//无压缩
biSizeImage=0;//没有压缩,因此可以为0
biXPelsPerMeter=0;
双渗透计=0;
biClrUsed=0;
biclr=0;
}
公共无效存储(BinaryWriter bw)
{
存储(bw,null);
}
公共void存储(BinaryWriter bw,uint[]调色板)
{
//必须维护文件写入的顺序
写入(biSize);
写入(biWidth);
写入(biHeight);
写入(双平面);
写入(bibittcount);
写(双压缩);
写入(biSizeImage);
写入(biXPelsPerMeter);
bw.Write(双渗透计);
写入(biClrUsed);
写入(biclr重要);
//如果8 bpp或更低,则编写调色板

if(biBitCount)感谢您为我指明了正确的方向。我设计了一个解决方案(发布在下面),该解决方案基于您的代码片段,将位图对象转换为1 bpp位图字节流。假设您不知道Win32.DeleteObject(和其他Win32方法)的来源?我的解决方案中有一个Win32项目,但它没有这些方法。您自己滚动过它们吗(或者这么长时间后您还记得吗?)它们是coredll.dll中的P/Invoke函数。示例:[dlliport(“coredll.dll”)]public static extern void DeleteObject(IntPtr hObj);谢谢-这帮了我很大的忙。我遇到了一个问题,它只是创建了一个普通的黑色图像?