今日は10時からのガイアの夜明けでIKEAが出るそうです。私は別にIKEA好きではありませんが、あの物がバーッと整然と美しく並んでいる感じが大好きです。ですから私は大きなホームセンターなんかに行くと心躍ります。
...とはいっても買うものは洗剤とか、しょうもないモノだけですけどね。すでに私の買い物はほとんどamazonでまとめ買いです。(店員さんスイマセン。だって安いんだもの。)
さて、今日は前回の続きバイナリの生データを扱います。今回は書き込みです。
プログラムは前回のものを少し変更して使います。流れとしてはPNGかどうか確認し、
PNGならサイズを改変して取り出すという流れになります。改変するので、必ずどうでもいいPNG画像を使用してください。ではコードを
QSize getPngImageSize( QIODevice *device ) { quint32 width = 0; quint32 height = 0; char signature[8]; char chunkType[4]; char custumSize[8] = { 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00}; QDataStream in( device ); in.readRawData( signature, 8 ); if ( memcmp(signature, "\211PNG\r\n\32\n", 8) == 0 ) { while ( !in.atEnd() ) { device->seek(device->pos() + 4); in.readRawData( chunkType, 4 ); if ( memcmp(chunkType, "IHDR", 4) == 0 ) { in.writeRawData(custumSize, 8);//サイズ変更(256×256) device->seek(device->pos() - 8);//書込み時に進んでしまうので位置を戻す in >> width >> height; break; } // jump to the next chunk device->seek(device->pos() + 4); } } return QSize( width, height ); }
宣言部は前回とほぼ同じです。custumSizeのみ追加しています。これに縦横のサイズをいれます。今回は256×256になるようにしています。
その後のin.writeRawDataの位置までは前回と同じです。PNGフォーマットかどうかを確認し、そうならループに突入。"IHDR"の位置に入ったらサイズを変更してから取り出します。in.writeRawDataでサイズ変更しています。一応リファレンスを
int QDataStream::writeRawData ( const char * s, int len )
sをlenバイトを書き込む。書込みが成功すると書き込んだバイト数が返る。エラーなら-1が返る。データはエンコードされない。(リファレンスへ)
です。後の説明は前回と同じなので省きます。
でgetPngImageSizeを使うには
void sample()//上のgetPngImageSizeを使用する関数 { QFile file(tr("/home/ubuntu001/io.png")); if ( file.open(QIODevice::ReadWrite) )//読み書きモードで開けたかチェック { QSize size = getPngImageSize( &file );//サイズ取得 ui->lineEdit->setText(tr("%1: %L2 x %L3").arg("io.png").arg(size.width()).arg(size.height()));/*size表示*/ } else { ui->lineEdit->setText("error");//オープン失敗 } }
のようにします。file.open(QIODevice::ReadWrite)のところ以外は前回と同じです。
はい、以上です。次回からはテキストデータの読み書きをやっていきます。