直接从文件png读取数据

时间:2015-09-26 13:22:49

标签: png

需要从二进制文件中读取数据而不在Bitmap中加载它们因为它太多,超过20000x20000像素,我需要打开一个文件,一次一行读取文件进行处理。找到了一个阅读BMP的例子,无法理解如何以相同的方式从PNG获取数据。

        byte[] B = File.ReadAllBytes(filename);
        GCHandle GCH = GCHandle.Alloc(B, GCHandleType.Pinned);
        IntPtr Scan0 = (IntPtr)((int)(GCH.AddrOfPinnedObject()) + 54);
        int W = Marshal.ReadInt32(Scan0, -36);
        int H = Marshal.ReadInt32(Scan0, -32);
        Bitmap Bmp = new Bitmap(W, H, 4 * W, PixelFormat.Format32bppArgb, Scan0);
        GCH.Free();
        return Bmp;

语言C#

1 个答案:

答案 0 :(得分:0)

我找到了一个带解析块的库(PNGChunkParser),APG收到了文件中的所有块,我找到了一个21单位的Idate,但是试图将它们画成50行,不是正确的图片:

byte[] B = File.ReadAllBytes(filename);
        List<byte> tmpb = new List<byte>();
        using (MemoryStream stream = new MemoryStream(B))
        {
            PNGChunk[] chunks = PNGChunkParser.ChunksFromStream(stream).ToArray();
            foreach (PNGChunk item in chunks)
            {
                if (item.TypeString == "IDAT")
                {
                    PNGChunk idatChunk = item;
                    foreach (byte s in idatChunk.Data)
                    {
                        tmpb.Add(s);
                    }
                }
            }
        }
        var size_png = ImageHelper.GetDimensions(filename);
        GetConturPic(tmpb.ToArray(), size_png.Width, 50,PixelFormat.Format32bppArgb);          
         private void GetConturPic(byte[] data, int w, int h, PixelFormat pixel_format)
    {
        int index;
        int stride = GetStride(w, pixel_format);
        Bitmap bm = new Bitmap(w, h);
        Color fm = new Color();
        try
        {
            for (int y = 0; y < h; y++)
            {
                for (int x = 0; x < w; x++)
                {
                    index = y * stride + 4 * x;
                    fm = GetPixelColor(data, w, h, x, y,

             System.Drawing.Bitmap.GetPixelFormatSize(pixel_format));
                    bm.SetPixel(x, y, fm);
                }
                pictureBox1.Image = bm;
                pictureBox1.Refresh();
            }
        }
        catch (Exception ex)
        {
            listBox1.Items.Add(ex.Message);
        }
    }
    public Color GetPixelColor(byte[] Pixels, int w, int h, int x, int y, int depth)
    {
        Color clr = Color.Empty;
        // Get color components count
        int cCount = depth / 8;
        // Get start index of the specified pixel
        int i = ((y * w) + x) * cCount;
        if (i > Pixels.Length - cCount)
            throw new IndexOutOfRangeException();
        byte b, g, a, r, c;
        switch (depth)
        {
            case 32:
                b = Pixels[i];
                g = Pixels[i + 1];
                r = Pixels[i + 2];
                a = Pixels[i + 3]; // a
                clr = Color.FromArgb(a, b, g, r);
                break;
            case 24:
                b = Pixels[i];
                g = Pixels[i + 1];
                r = Pixels[i + 2];
                clr = Color.FromArgb(b, g, r);
                break;
            case 8:
                c = Pixels[i];
                clr = Color.FromArgb(c, c, c);
                break;
        }
        return clr;
    }

帮助获得50行图像需要做什么?