カテゴリでNSImageにリサイズ機能を付加する

Objective-Cのカテゴリの機能を使って、NSImageに指定したサイズにリサイズした新たなNSImageオブジェクトを生成する機能を追加してみます。
なお、この機能拡張はビットマップ系画像ファイルを読み込んで生成されたNSImageで動作させることを想定しており、PDFなどベクター系データを読み込んだNSImageでは動作しませんので悪しからず。

1.概要

NSImageに以下のメソッドを追加します。

// リサイズしたイメージの生成
- (NSImage *)resizedImageBy:(E_RESIZE_METHOD)eMethod newSize:(NSSize)tNewSize

    eMethod     リサイズ方法(使用するアルゴリズム)
                    MTHD_AREA_AVERAGING     面積平均法
                    MTHD_PIXEL_AVERAGING    平均画素法
                    MTHD_BILINEAR           Bilinear法
                    MTHD_BICUBIC            Bicubic法
    tNewSize    サイズ

画像拡縮アルゴリズムとしてはPhotoShopでおなじみNearest Neighbor法、Bilinear法、Bicubic法の3つが有名ですが、Nearest Neighbor法は速いけれども画質は最低レベルなので実装せず、そのかわりに面積平均法と平均画素法というアルゴリズムを実装しています。なお、面積平均法と平均画素法は縮小専門のアルゴリズムなので拡大には使用できません。

2.カテゴリの作成

ファイルメニューの新規ファイル作成でCocoaの「Objective-C class」を選択し、インプリメントファイルとヘッダファイルを作成します。(この例ではUCResizeImageというファイル名にしています)
作成されたクラスのスケルトンはNSObjectのサブクラスの定義となっているのでNSImageのカテゴリ定義となるように以下のように修正します。

●ヘッダファイル
    @interface UCResizeImage : NSObject {
    }
            ↓
    @interface NSImage (UCResizeImage)

●インプリメントファイル
    @implementation UCResizeImage
            ↓
    @implementation NSImage (UCResizeImage)

次にメソッドの定義と実装を行います。具体的にはソースを参照してください。
メンバ変数を追加できないという制約はありますが、これで追加したメソッドがNSImageの一部として機能するようになります。

3.テストアプリケーション

テスト用のアプリケーションは以下のような画面で、まずリサイズしたい画像ファイルを選択した後、サイズとアルゴリズムを指定してリサイズボタンをクリックするとリサイズされた画像がNSImageViewに表示されます。


4.画像拡縮アルゴリズムについて

各アルゴリズムの実装にあたっては以下のサイトを参考にさせていただきました。

●面積平均法
http://www.bea.hi-ho.ne.jp/gaku-iwa/pb/Tip/010/tip.html

●平均画素法
http://www.marumo.ne.jp/db2000_c.htm#18
12月18日〜21日の日記に縮小アルゴリズムについて書かれています。

●Bilinear法
http://www.pcigeomatics.com/cgi-bin/pcihlp/GCPWORKS%7CTheory%7CResampling

●Bicubic法
http://astronomy.swin.edu.au/~pbourke/colour/bicubic/

他にも3-lobed Lanczos-windowed sinc(Lanczos3)というアルゴリズムにも挑戦したのですがうまくいかず挫折してしまいました (T_T)。しばらくして再チャレンジしたいと思います
Lanczos3については以下のサイトを参考にしてください。

http://www.worldserver.com/turk/computergraphics/ResamplingFilters.pdf
http://www.marumo.ne.jp/db2001_7.htm#4
http://www.marumo.ne.jp/auf/#lpf

ちなみに1番目のURLはAppleの技術者の書いた論文で、最後のURLには動画のリサイズ用プラグインのソースが掲載されています。

5.その他

このリサイズ機能の性能ははっきり言ってあまりよくありません(^_^;)。AltiVecに対応していないのはもちろんなのですが、アルファチャンネルの有無やサンプル毎のビット数などのピクセルフォーマットを意識しないために、NSBitmapImageRepのgetPixel:atX:y:を使ってオリジナルのビットマップに頻繁にアクセスしていることもその一因と思われます。

サンプルプログラムのダウンロード(60KB)

【作成・確認環境】
Mac OS X v10.4.2
Xcode v2.0

一覧に戻る