No.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;
}
この回答へのお礼
お礼日時:2011/07/01 13:35
回答ありがとうございます。
何とか先ほど自力でできたのですが、
回答していただいたものを参考にさらに精進しようと思います。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C#テキストボックスの文字を配列にいれてその後表示する 4 2022/07/17 04:47
- Excel(エクセル) Excelで、あるセルだけ入力させたい、オートフィルターも使わせたい際のシートの保護 2 2023/02/23 15:14
- ニコニコ動画 【Premiere Pro】をお使いの方 カット作業を他動画に反映することはできますか? 1 2022/05/18 16:27
- Perl perlで2次元配列をサブルーチンに値渡しで渡す 5 2022/12/17 18:49
- Excel(エクセル) Excelで数式またはマクロを使用してできるか教えてください。 7 2023/01/11 18:20
- Visual Basic(VBA) 【VBA】もし、値が0だったら左のセルと合わせて削除したい 3 2023/04/20 10:12
- 英語 節を列挙する例示表現について 2 2022/08/15 13:52
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- その他(プログラミング・Web制作) PythonでLoopを使って配列内の文字列を結合する。そして [] を削除する 1 2022/03/31 23:28
- Excel(エクセル) 同じ品番のマスタで最新日付のものに〇印を入れたい 3 2023/03/31 17:45
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
fgetsなどのときのstdinのバッ...
-
ftoa の作り方
-
C言語のfor文です。 繰り返しの...
-
エンディアン:2バイトのデー...
-
絶対パスからのファイル名の切...
-
テキストデータをそのままバイ...
-
charでの計算?
-
strtol関数 自作
-
C言語の入力した文字を反転させ...
-
3桁区切(コンマ)記号をつけ...
-
「ポインタのポインタ」を使っ...
-
【C言語】文字型と整数型の違い
-
コマンドラインに入力されてい...
-
c言語配列の結合についてです。...
-
配列をnビットシフトする
-
str系関数を使わずに二つの文字...
-
【C言語】構造体内の領域解放(...
-
文字列から空白を取り除きたい...
-
atoi( ) の反対をやりたい
-
OpenCVで32bit ヘッダ無しRaw画...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
charからLPTSTRへの変換方法
-
charでの計算?
-
配列をnビットシフトする
-
'const char *' 型は 'char *' ...
-
型変換
-
テキストデータをそのままバイ...
-
文字列から空白を取り除きたい...
-
CStringをwchar_tに変換したい
-
絶対パスからのファイル名の切...
-
fgetsなどのときのstdinのバッ...
-
ネットワークにつながっている...
-
str系関数を使わずに二つの文字...
-
3桁区切(コンマ)記号をつけ...
-
atoi( ) の反対をやりたい
-
double型の値をchar配列に変換...
-
C言語のfor文です。 繰り返しの...
-
switch文で文字を比較すること...
-
ファイル名である文字列からbas...
-
c++ 文字列を入力して、一文字...
-
strncpyと_tcsncpy_sのヌルの扱...
おすすめ情報