示例#1
0
        public static unsafe byte[] FromBitmap(Bitmap Picture, ImageFormat Format, bool ExactSize = false)
        {
            if (ExactSize && ((Picture.Width % 8) != 0 || (Picture.Height % 8) != 0))
            {
                return(null);
            }
            int physicalwidth  = Picture.Width;
            int physicalheight = Picture.Height;
            int ConvWidth      = Picture.Width;
            int ConvHeight     = Picture.Height;

            if (!ExactSize)
            {
                ConvWidth  = 1 << (int)Math.Ceiling(Math.Log(Picture.Width, 2));
                ConvHeight = 1 << (int)Math.Ceiling(Math.Log(Picture.Height, 2));
            }
            BitmapData d   = Picture.LockBits(new Rectangle(0, 0, Picture.Width, Picture.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            uint *     res = (uint *)d.Scan0;

            byte[] result = new byte[ConvWidth * ConvHeight * GetBpp(Format) / 8];
            int    offs   = 0;

            switch (Format)
            {
            case ImageFormat.RGB8:
                for (int y = 0; y < ConvHeight; y += 8)
                {
                    for (int x = 0; x < ConvWidth; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int   pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            Color c   = Color.FromArgb((int)res[(y + y2) * d.Stride / 4 + x + x2]);
                            result[offs + pos * 3 + 0] = c.B;
                            result[offs + pos * 3 + 1] = c.G;
                            result[offs + pos * 3 + 2] = c.R;
                        }
                        offs += 64 * 3;
                    }
                }
                break;

            case ImageFormat.RGB565:
                for (int y = 0; y < ConvHeight; y += 8)
                {
                    for (int x = 0; x < ConvWidth; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            IOUtil.WriteU16LE(result, offs + pos * 2, GFXUtil.ArgbToRGB565(res[(y + y2) * d.Stride / 4 + x + x2]));
                        }
                        offs += 64 * 2;
                    }
                }
                break;

            case ImageFormat.ETC1:
            case ImageFormat.ETC1A4:
                for (int y = 0; y < ConvHeight; y += 8)
                {
                    for (int x = 0; x < ConvWidth; x += 8)
                    {
                        for (int i = 0; i < 8; i += 4)
                        {
                            for (int j = 0; j < 8; j += 4)
                            {
                                if (Format == ImageFormat.ETC1A4)
                                {
                                    ulong alpha = 0;
                                    int   iiii  = 0;
                                    for (int xx = 0; xx < 4; xx++)
                                    {
                                        for (int yy = 0; yy < 4; yy++)
                                        {
                                            uint color = res[((y + i + yy) * (d.Stride / 4)) + x + j + xx];
                                            uint a     = color >> 24;
                                            a    >>= 4;
                                            alpha |= (ulong)a << (iiii * 4);
                                            iiii++;
                                        }
                                    }
                                    IOUtil.WriteU64LE(result, offs, alpha);
                                    offs += 8;
                                }
                                Color[] pixels = new Color[4 * 4];
                                for (int yy = 0; yy < 4; yy++)
                                {
                                    for (int xx = 0; xx < 4; xx++)
                                    {
                                        pixels[yy * 4 + xx] = Color.FromArgb((int)res[((y + i + yy) * (d.Stride / 4)) + x + j + xx]);
                                    }
                                }
                                IOUtil.WriteU64LE(result, offs, ETC1.GenETC1(pixels));
                                offs += 8;
                            }
                        }
                    }
                }
                break;

            default:
                throw new NotImplementedException("This format is not implemented yet.");
            }
            return(result);
        }