Cocoaでいこう! Macらしく 第18回
Yoshiki(DreamField)
この記事は、MOSAが発行するデベロッパ向けのデジタルマガジンMOSADeN 第79号(2003年8月26日発行)に掲載された記事です。2〜3ヶ月遅れで、ここに掲載して行きます。

保存フォーマットを選べるようにしよう

現在のTinyViewでは保存フォーマットを選べません。これを選べるようにしましょう。

実はこれもある程度まで、フレームワークに任せることが出来ます。ターゲットから書類のタイプを表示させて下さい。そして、JPEGとPICTの役割を見て下さい。今はViewerになっているはずです。これを両方ともEditorに変更して下さい(fig.01)。

役割をEditorに変更する
[fig.01] 役割をEditorに変更する

そしてビルドして実行してみて下さい。今までと違って、何も画像が表示されていない空のウィンドウが勝手に開いたと思います(fig.02)。

TinyViewを起動すると、勝手に空のウィンドウが開く
[fig.02] TinyViewを起動すると、勝手に空のウィンドウが開く

※もし、空のウィンドウが開かなかった場合は、一度TinyViewを終了させてInterfaceBuilderに戻り、クリーニングを行ってから、再度、ビルドして実行して下さい。クリーニングは、ほうきのアイコンをクリックすることにより、行うことができます。

開いてしまった空のウィンドウは無視して、何かJPEGかPICTの画像を開いてみて下さい。そして、Save As...を選んでSaveパネルを開いてみて下さい(間違えてSaveを選ばないように、注意して下さい。ここでSaveを選ぶと、元データに上書きしてしまいます。)。すると、一番下にFile Formatという項目が追加されていると思います。ここからJPEGとPICTを選べるようになっているはずです(fig.03)。

保存フォーマットを選べるようになっている
[fig.03] 保存フォーマットを選べるようになっている

Hide extensionにチェックが入っているのなら外してみましょう。JPEGとPICTを選ぶたびに、拡張子も変化するのが分かります。この様に、選ぶ部分まではフレームワークに任せることができます。ただし、自動的にフォーマットの変換まではしてくれません。それはまだ実装していませんので、今はCancelボタンを押して、保存するのを中止して下さい。

まずはJPEGに変換する仕組みを実装しましょう。今は、単純に開いたデータを返しているだけのdataRepresentationOfType:を、次の様に修正してください。

- (NSData *)dataRepresentationOfType:(NSString *)aType
{
    NSData *theTiffData;
    NSBitmapImageRep *theBitmapImageRep;
    NSDictionary *theProperty;
    NSData *theData;

    theData = nil;
    if( [ aType isEqualToString:@"JPEG"]){
        theTiffData = [ image TIFFRepresentation];
        theBitmapImageRep = [ NSBitmapImageRep imageRepWithData:theTiffData ];
        theProperty = [ NSDictionary dictionaryWithObjectsAndKeys:[ NSNumber numberWithFloat:0.5],
    NSImageCompressionFactor, nil ];
        theData = [ theBitmapImageRep representationUsingType:NSJPEGFileType properties:theProperty];
    }
    return theData;
}

順番に見て行きましょう(必用に応じてリファレンスマニュアルと照らし合わせながら見て下さい。)。

theData = nil;

一行ずつ見て行きましょう。

tyeType = nil;

変換した結果のアドレスを入れる領域に初期値としてnilを入れておきます。

if( [ aType isEqualToString:@"JPEG"]){

どのフォーマットで保存して欲しいのかは、aTypeで渡って来ます。そこで、これが@"JPEG"であるのか判別します。@"JPEG"であれば、JPEGへの変換処理を行います。

theTiffData = [ image TIFFRepresentation];

NSImageのインスタンスから直接JPEGには変換できないので、まずはTIFFに変換します。

theBitmapImageRep = [ NSBitmapImageRep imageRepWithData:theTiffData ];

変換したTIFFから、NSBitmapImageRepクラスのインスタンスを生成します。NSBitmapImageRepからはJPEGに変換することができます。

theProperty = [ NSDictionary dictionaryWithObjectsAndKeys:
              [ NSNumber numberWithFloat:0.5], NSImageCompressionFactor, nil ];

JPEGに変換する時にはパラメタを必用とします。パラメタはNSDictionaryクラスのインスタンスにセットして渡します。ここでは、圧縮率を決め打ちで指定しています。本来なら圧縮率を選べるようにすべきだと思いますが、学習用のプログラムですので、ここでは分かりやすいように手を抜いておきます。

theData = [ theBitmapImageRep representationUsingType:NSJPEGFileType
                                           properties:theProperty];

そして、NSBitmapImageRepクラスのインスタンスからJPEGデータに変換しています。

return theData;

変換したデータを返します。これで、開いた画像のフォーマットが何であっても、JPEGに変換して保存できるようになりました。適当なファイルを開いて試してみて下さい(保存は必ずSave As...の方で行って下さい。Saveで保存しますと、警告も何も出ずに、元データに上書きしてしまいます。)。

JPEGでの保存はできるようになりました。でも、PICTフォーマットを指定した時はnilが返りますので、PICTでの保存はできません。これもJPEG同様、変換処理を実装する必用があります。ところが、CocoaではPICTフォーマットに変換する機能は提供されていないのです。これは困りました。この続きは次回です。

前頁目次次頁