プロが教える店舗&オフィスのセキュリティ対策術

RotateFlip(RotateFlipType.RotateNoneFlipY)
を使わず、
bmpをbyte配列に読み込み、配列の並べ替えのみで行いたいのですが
可能でしょうか?

可能であれば教えていただきたいです。
よろしくお願いいたします。

A 回答 (1件)

反転でも回転でもなんでも出来ます。



Bitmapのデータ構造は大雑把にいうと
1ライン分のRGB情報が終端から順番にセットされています。
なので、ライン毎に逆順にリプレースすれば反転出来ます。

Bitmapのフォーマットの詳細についてはこちら
http://www.kk.iij4u.or.jp/~kondo/bmp/

サンプル

#define BFT_BITMAP0x4d42
#define WIDTHBYTES(bits)(((bits) + 31) / 32 * 4)

class Bmp24
{
public:
//コンストラクタ
Bmp24() : _buffer( NULL )
{
}
//コピーコンストラクタ
Bmp24( const Bmp24& bmp ) : _buffer( NULL )
{
operator=( bmp );
}
//デストラクタ
virtual ~Bmp24()
{
close();
}
//代入オーバーロード
const Bmp24& operator=( const Bmp24& bmp )
{
close();
bmp.duplicate( &_buffer );
return *this;
}
//複製
void duplicate( unsigned char** buffer ) const
{
if( _buffer )
{
PBITMAPFILEHEADER header = ( PBITMAPFILEHEADER )_buffer;
*buffer = new unsigned char[ header->bfSize ];
memcpy( *buffer, _buffer, header->bfSize );
}
}
//画像幅(pixel)
inline int width() const
{
if( _buffer )
{
return infoHeader()->biWidth;
}
return -1;
}
//画像高さ(pixel)
inline int height() const
{
if( _buffer )
{
return infoHeader()->biHeight;
}
return -1;
}
//1ライン取得
unsigned char* getLine( const int y, int& length ) const
{
if( _buffer && 0 <= y && height() > y )
{
length = lineWidth();
return imageBits() + ( y * length );
}
return NULL;
}
//1ライン上書きコピー
void setLine( const int y, unsigned char* buffer, int length ) const
{
if( _buffer && 0 <= y && height() > y )
{
if( length == lineWidth() )
{
memcpy( imageBits() + ( y * length ), buffer, length );
}
}
}
//BMPのロード
bool open( const char* fileName )
{
bool result = false;

FILE* stream = fopen( fileName, "rb" );
if( !stream )
{
return result;
}

do
{
size_t count = 0;
BITMAPFILEHEADER header = { 0 };

count = fread( &header, sizeof( header ), 1, stream );
if( ( count != 1 ) ||
( BFT_BITMAP != header.bfType ) ||
( 0 != header.bfReserved1 ) ||
( 0 != header.bfReserved2 ) )
{
break;
}

_buffer = new unsigned char[ header.bfSize ];

memcpy( _buffer, &header, sizeof( header ) );

count = fread( _buffer + sizeof( header ), header.bfSize - sizeof( header ), 1, stream );
if( count != 1 )
{
delete[] _buffer;
_buffer = NULL;
break;
}

result = true;
}
while( 0 );

fclose( stream );

return result;
}
//BMPのクローズ
void close()
{
if( _buffer )
{
delete[] _buffer;
_buffer = NULL;
}
}
//画像反転
void turnAround()
{
Bmp24 temp( *this );//リプレースのための一時バッファ
unsigned char* ptr;
int length = 0;
for ( int y = 0 ; temp.height() > y ; y++ )
{
//逆順にライン情報をとってきて
ptr = temp.getLine( temp.height() - 1 - y, length );
//昇順にライン情報をセットする
this->setLine( y, ptr, length );
}
}
//ファイルへ保存
bool saveFile( const char* fileName )
{
FILE* stream = fopen( fileName, "wb" );
if( !stream )
{
return false;
}

size_t count = 0;
if( _buffer )
{
count = fwrite( _buffer, fileHeader()->bfSize, 1, stream );
}

fclose( stream );

return( 1 == count );
}

protected:

inline PBITMAPFILEHEADER fileHeader() const
{
if( _buffer )
{
PBITMAPFILEHEADER header = ( PBITMAPFILEHEADER )( _buffer );
return header;
}
return NULL;
}

inline PBITMAPINFOHEADER infoHeader() const
{
if( _buffer )
{
PBITMAPINFOHEADER header = ( PBITMAPINFOHEADER )( _buffer + sizeof( BITMAPFILEHEADER ) );
return header;
}
return NULL;
}

inline unsigned char* imageBits() const
{
if( _buffer )
{
return _buffer +
fileHeader()->bfOffBits +
( infoHeader()->biClrUsed * sizeof( RGBQUAD ) );
}
return NULL;
}

inline int lineWidth() const
{
return WIDTHBYTES( infoHeader()->biBitCount * infoHeader()->biWidth );
}

unsigned char* _buffer;
};


int main(int argc, char* argv[])
{
if( 3 != argc ) return -1;

Bmp24 bmp;
bmp.open( argv[ 1 ] );
bmp.turnAround();
bmp.saveFile( argv[ 2 ] );
return 0;
}
    • good
    • 0
この回答へのお礼

回答ありがとうございます。


何とか先ほど自力でできたのですが、
回答していただいたものを参考にさらに精進しようと思います。

ありがとうございました。

お礼日時:2011/07/01 13:35

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!