예제 #1
0
            /// <summary>
            /// BMPに変換して出力
            /// </summary>
            /// <param name="fileName">出力ファイル名</param>
            /// <returns>RESULTタイプ</returns>
            public RESULT OutputBMP(string fileName)
            {
                // 独自のBITMAPFILEHEADERとBITMAPINFOHEADERを使って出力します
                // ※Silverlightなどアンセーフを使えない環境用

                // 作成されていない or 読み込まれていない
                if (m_pImage == null || m_ImageSize == 0)
                {
                    return(RESULT.ERROR_IMAGE);
                }

                // パレットありなのに設定されていない
                if (m_PaletteColor != 0 && m_pPalette == null)
                {
                    return(RESULT.ERROR_PALETTE);
                }

                // 配列が変わるのでコピーを作成
                BasePict bmpPict = new BasePict(this);

                try
                {
                    bmpPict.m_pImage = new byte[bmpPict.m_ImageSize];
                    Array.Copy(m_pImage, 0, bmpPict.m_pImage, 0, m_ImageSize);

                    if (bmpPict.m_PaletteColor != 0)
                    {
                        bmpPict.m_pPalette = new byte[bmpPict.m_PaletteSize];
                        Array.Copy(m_pPalette, 0, bmpPict.m_pPalette, 0, m_PaletteSize);
                    }
                }
                catch
                {
                    System.Diagnostics.Debug.WriteLine("出力用のメモリ確保に失敗");
                    return(RESULT.ERROR_MEMORY);
                }

                // 左→右、下→上配列に変換
                if (!bmpPict.ConvertBitType(TGA.LINE.IMAGE_LINE_LRDU))
                {
                    return(RESULT.ERROR_OUTPUT);
                }

                try
                {
                    // BMPヘッダーの作成
                    BITMAPFILEHEADER bmHead = new BITMAPFILEHEADER();
                    BITMAPINFOHEADER bmInfo = new BITMAPINFOHEADER();

                    int paletteSize = bmpPict.m_PaletteColor << 2;
                    bmHead.bfSize    += (UInt32)(bmpPict.m_ImageSize + paletteSize);
                    bmHead.bfOffBits += (UInt32)paletteSize;

                    bmInfo.biWidth    = bmpPict.m_ImageW;
                    bmInfo.biHeight   = bmpPict.m_ImageH;
                    bmInfo.biBitCount = (UInt16)bmpPict.m_ImageBit;

                    // BMP出力
                    using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))
                    {
                        using (BinaryWriter bwrite = new BinaryWriter(fs))
                        {
                            // ヘッダー
                            bmHead.WriteHeader(bwrite);
                            bmInfo.WriteHeader(bwrite);

                            // パレット
                            if (bmpPict.m_pPalette != null)
                            {
                                if (bmpPict.m_PaletteBit == 32)
                                {
                                    bwrite.Write(bmpPict.m_pPalette, 0, bmpPict.m_PaletteSize);
                                }
                                else if (bmpPict.m_PaletteBit == 24)
                                {
                                    // αを追加する
                                    int        ofs = 0;
                                    const byte A   = 0xff; // 見た目的に0x00の方がいい?
                                    for (int i = 0; i < bmpPict.m_PaletteColor; i++)
                                    {
                                        bwrite.Write(bmpPict.m_pPalette[ofs++]);
                                        bwrite.Write(bmpPict.m_pPalette[ofs++]);
                                        bwrite.Write(bmpPict.m_pPalette[ofs++]);
                                        bwrite.Write(A);
                                    }
                                }
                                else if (bmpPict.m_PaletteBit == 16)
                                {
                                    int    offset = 0;
                                    byte   r, g, b, a;
                                    UInt16 rgba;

                                    for (int i = 0; i < bmpPict.m_PaletteColor; i++)
                                    {
                                        rgba    = BitConverter.ToUInt16(bmpPict.m_pPalette, offset);
                                        offset += 2;

                                        a = (byte)(MASK.getA1(rgba) * 0xff);
                                        r = (byte)(MASK.getR5(rgba) << 3);
                                        g = (byte)(MASK.getG5(rgba) << 3);
                                        b = (byte)(MASK.getB5(rgba) << 3);

                                        byte[] plt = BitConverter.GetBytes(MASK.getRGBA8888(r, g, b, a));
                                        bwrite.Write(plt[2]);
                                        bwrite.Write(plt[1]);
                                        bwrite.Write(plt[0]);
                                        bwrite.Write(plt[3]);
                                    }
                                }
                                else
                                {
                                    System.Diagnostics.Debug.WriteLine("対応していないビット数のパレット");
                                    return(RESULT.ERROR_PALETTE);
                                }
                            }

                            // イメージ
                            bwrite.Write(bmpPict.m_pImage, 0, bmpPict.m_ImageSize);

                            /*
                             * // 4バイトサイズに調整
                             * UInt32 diffSize = Utility.BOUND((int)bmHead.bfSize, 4) - bmHead.bfSize;
                             * if (0 < diffSize)
                             * {
                             *  byte[] padd = new byte[diffSize];
                             *  bwrite.Write(padd, 0, padd.Length);
                             *  bmHead.bfSize += diffSize;
                             * }
                             */
                        }
                    }
                }
                catch
                {
                    return(RESULT.ERROR_OUTPUT);
                }

                return(RESULT.ERROR_NONE);
            }