public static System.Drawing.Bitmap CreateBitmap(byte[] data, int width, int height, int pixelOffset) { int BlockSize = 8; int physicalWidth = DXTUtility.GetBlockCount(width) * 4; int physicalHeight = DXTUtility.GetBlockCount(height) * 4; var pixels = new byte[physicalWidth * physicalHeight * 4]; var blocks = DXTUtility.EnumerateBlocks(width, height, pixelOffset, BlockSize); foreach (var block in blocks) { // ここで block をデコードし pixel 配列の該当位置にRGBAデータを展開する ushort color0 = BinaryUtility.MakeUInt16(data, block.Offset); ushort color1 = BinaryUtility.MakeUInt16(data, block.Offset + 2); var colors = new ColorRgba[4]; if (color0 > color1) { // アルファなし。使える色は4色 colors[0] = ColorRgba.FromRgb565(color0); // カラー0そのまま colors[1] = ColorRgba.FromRgb565(color1); // カラー1そのまま colors[2] = ColorRgba.Lerp(colors[0], colors[1], 1.0f / 3.0f); // color_2 = 2/3*color_0 + 1/3*color_1 colors[3] = ColorRgba.Lerp(colors[0], colors[1], 2.0f / 3.0f); // color_3 = 1/3*color_0 + 2/3*color_1 } else { // アルファあり。使える色は3色 colors[0] = ColorRgba.FromRgb565(color0); // カラー0そのまま colors[1] = ColorRgba.FromRgb565(color1); // カラー1そのまま colors[2] = ColorRgba.Lerp(colors[0], colors[1], 1.0f / 2.0f); // color_2 = 1/2*color_0 + 1/2*color_1 colors[3] = new ColorRgba(0, 0, 0, 0); // 透明 } uint indexBits = BinaryUtility.MakeUInt32(data, block.Offset + 4); for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { var idx = indexBits & 0x03; // インデックスの取り出し var col = colors[idx]; // カラーテーブルからインデックスでカラーを取り出す int xx = block.X + x; int yy = block.Y + y; int p = (xx + yy * physicalWidth) * 4; // ピクセルの書き込み位置 pixels[p + 0] = (byte)(col.B * 255.0f); // 青(0~255) pixels[p + 1] = (byte)(col.G * 255.0f); // 緑(0~255) pixels[p + 2] = (byte)(col.R * 255.0f); // 赤(0~255) pixels[p + 3] = (byte)(col.A * 255.0f); // アルファ(0~255) indexBits >>= 2; // インデックスを2ビット右シフトして次に備える } } } return(CreateBitmap2(pixels, width, height, physicalWidth)); }
public static DdsSimpleFileInfo GetDdsInfo(byte[] data) { const int HeaderSize = 0x80; var info = new DdsSimpleFileInfo(); // 情報クラスを作成 if (data.Length < HeaderSize) { return(info); // DDSとしてのヘッダサイズが足りない } var magic = Encoding.UTF8.GetString(data, 0, 4); // data 配列の先頭から連続する4バイトを文字列に変換 if (magic != "DDS ") { return(info); // DDSファイルではない } // 画像の横幅と高さ info.Height = (int)BinaryUtility.MakeUInt32(data, 0x0c); // data 配列の 12バイト目から連続する4バイトをInt32に変換 info.Width = (int)BinaryUtility.MakeUInt32(data, 0x10); // data 配列の 16バイト目から連続する4バイトをInt32に変換 info.PixelOffset = HeaderSize; // ピクセルデータの開始位置 // DXT1形式かどうかをチェック info.Format = Encoding.UTF8.GetString(data, 0x54, 4); var byte1 = data[0x54]; var byte2 = data[0x55]; var byte3 = data[0x56]; var byte4 = data[0x57]; switch (info.Format) { case "DXT1": break; default: return(info); } info.IsValid = true; // ヘッダ取得成功を示すフラグを設定 return(info); }