ロゴ メインコンテンツへ
RSSフィード
「ソフトウェア開発」に関連する記事一覧

Java 画像データ用クラス

2011/12/08
(2018/11/13 最終更新)
(この記事の文字数: 673)

普段Javaはあまり使わないのですが、大学の授業の関係で久しぶりに触りました。

いつもはC++で画像処理をやっているのですが、Javaで画像を扱おうとするとどんな感じになるのかと疑問に思ったので、簡単な画像データ用のクラスを作ってみました。

以下が作成したクラスです。機能的には画像用メモリの確保とRGBAデータのget & setだけです。


/*!
 *  WspImage is a class which access to some of manipulation of image
*/
public class WspImage
{
    private int width_=0, height_=0;
    private int[] rgba_data_=null;
    
    //** Constructors ------------------- 
    WspImage(int width, int height){
        Resize(width, height);
    }

    //** Accessors ---------------------- 
    int width(){ return width_; }
    int height(){ return height_; }
    int[] rgba_data(){ return rgba_data_; }
    int GetR(int index)
    { return (rgba_data_[index] & 0xff000000)>>24; }
    int GetG(int index)
    { return (rgba_data_[index] & 0x00ff0000)>>16; }
    int GetB(int index)
    { return (rgba_data_[index] & 0x0000ff00)>>8; }
    int GetA(int index)
    { return (rgba_data_[index] & 0x000000ff); }
    
    int GetR(int x, int y){ return GetR(y*width_+x); }
    int GetG(int x, int y){ return GetG(y*width_+x); }
    int GetB(int x, int y){ return GetB(y*width_+x); }
    int GetA(int x, int y){ return GetA(y*width_+x); }

    //** Mutators ----------------------- 
    void Resize(int width, int height){
        rgba_data_ = new int[width*height];
        width_ = width;
        height_ = height;
    }
    void SetR(int r, int index)
    { rgba_data_[index] = (rgba_data_[index] & 0x00ffffff) + (r<<24); }
    void SetG(int g, int index)
    { rgba_data_[index] = (rgba_data_[index] & 0xff00ffff) + (g<<16); }
    void SetB(int b, int index)
    { rgba_data_[index] = (rgba_data_[index] & 0xffff00ff) + (b<<8); }
    void SetA(int a, int index)
    { rgba_data_[index] = (rgba_data_[index] & 0xffffff00) + a; }
    
    void SetR(int r, int x, int y){ SetR(r, y*width_+x); }
    void SetG(int g, int x, int y){ SetG(g, y*width_+x); }
    void SetB(int b, int x, int y){ SetB(b, y*width_+x); }
    void SetA(int a, int x, int y){ SetA(a, y*width_+x); }
    
};

この画像用データクラスを作ってJavaとC++の違いから感じた利点・欠点を以下に挙げます。

  • 符号なしbyteデータ型がJavaにはないのでintなどで代用する必要がある
  • オペレータオーバーロードがJavaはできないので要素アクセスに[]が使えないのが不便
  • JavaはGCのおかげでメモリ開放操作が不要なのが楽
  • Javaは引数の既定値の設定ができないのが不便
  • Javaは1ファイルにクラス1つなので小さいクラスも別ファイルに書かなければならない

思ったより実装の違いは多くありませんでしたが、やはりメモリ開放を考えなくていいのはかなり楽です。でも、このメモリ操作をいかに効率よくやるのかという部分も慣れてくるとプログラミングの楽しみになってくるんですけどね。

ついでに、あまり役には立たないですが、RGBAひとつのデータだけを扱うデータクラスも載せておきます。


public class WspRgba
{
    private int data_;
    
    WspRgba(int r, int g, int b, int a){
        data_ = (r<<24) | (g<<16) | (b<<8) | a;
    }
    
    //** accessors
    int data(){ return data_; }
    int r(){ return ((data_ & 0xff000000)>>24);}
    int g(){ return ((data_ & 0x00ff0000)>>16);}
    int b(){ return ((data_ & 0x0000ff00)>>8);}
    int a(){ return ((data_ & 0x000000ff));}
    
    //** mutators
    void set_r(int r){ data_ = (data_ & 0x00ffffff) + (r<<24); }
    void set_g(int g){ data_ = (data_ & 0xff00ffff) + (g<<16); }
    void set_b(int b){ data_ = (data_ & 0xffff00ff) + (b<<8); }
    void set_a(int a){ data_ = (data_ & 0xffffff00) + a; }
};

最初はこのWspRgbクラスを要素にした画像クラスを作ろうと思ったのですが、Javaだとクラスで配列を作ろうとすると強制的にポインタの配列になってしまい、要素ひとつずつに別個メモリ確保が必要になってしまい、効率を悪くなってしまうので素直にint配列にしました。


  このエントリーをはてなブックマークに追加  

<<「ソフトウェア開発」の記事一覧に戻る

<<「ソフトウェア開発」の次の記事
「ソフトウェア開発」の前の記事 >>

コメント(0 件)



コンテンツロード: 0.0077 sec
Copyright(C)2006-2024 puarts All Rights Reserved