Class: Rixmap::Image
- Inherits:
-
Object
- Object
- Rixmap::Image
- Defined in:
- src/rixmapcore.cxx,
src/rixmapcore.cxx,
lib/rixmap/image.rb
Overview
画像クラス.
Defined Under Namespace
Classes: Line
Instance Method Summary collapse
-
#==(argObject) ⇒ Boolean
オブジェクトと比較して、同じ画像かどうかを返します.
-
#[](*args) ⇒ Object
指定したスキャンラインまたはピクセルデータを取得します.
-
#[]=(*args) ⇒ Object
スキャンラインまたはピクセルを更新します.
-
#background ⇒ Rixmap::Color, ...
背景色を取得します.
-
#background=(argColor)
背景色を設定します.
-
#convert(argMode) ⇒ Rixmap::Image
画像形式を変換します.
-
#crop(argLeft, argTop, argRight, argBottom) ⇒ Rixmap::Image
指定領域の部分画像を取得します.
-
#crop!(argLeft, argTop, argRight, argBottom) ⇒ Rixmap::Image
この画像を指定領域の部分画像に切り詰めます.
-
#deform(deformer, *args) ⇒ Rixmap::Image
指定されたDeformer::BaseDeformerインスタンスを使って変形処理を実行します.
-
#deform!(deformer, *args) ⇒ Rixmap::Image
指定されたDeformer::BaseDeformerインスタンスを使って破壊的に変形処理を実行します.
-
#dimension ⇒ Array<Integer>
画像の寸法を配列で返します.
-
#each_line ⇒ Object
スキャンライン走査するイテレータを返します.
-
#each_pixel ⇒ Object
ピクセルを走査するイテレータを返します.
-
#fill(*args) ⇒ Object
指定色で塗りつぶした画像を返します.
-
#fill!(*args) ⇒ Object
画像を指定色で破壊的に塗りつぶします.
-
#flip(argDirection) ⇒ Rixmap::Image
指定方向に反転を行った画像を返します.
-
#flip!(argDirection) ⇒ Rixmap::Image
指定方向に破壊的に反転処理を行います.
-
#get_bounds(width, height, anchor) ⇒ Array<Integer>
private
#resize用に
anchor
から[left, top, right, bottom]形式の配列を作成します. -
#grayscale? ⇒ Boolean
この画像がグレースケール形式かどうかを返します.
-
#has_alpha? ⇒ Boolean
この画像が透明度を持っているかを返します.
-
#height ⇒ Integer
画像の高さを取得します.
-
#indexed? ⇒ Boolean
この画像がインデックスカラー形式かどうかを返します.
-
#initialize(mode, width, height, options = {})
constructor
private
新規画像を作成します.
-
#initialize_copy(argObject)
private
複製されたオブジェクトを初期化します.
-
#inspect ⇒ String
オブジェクトとしての文字列表現を返します.
-
#lines ⇒ Array<Rixmap::Image::Line>
この画像の全てのスキャンラインを含む配列を返します.
-
#mode ⇒ Rixmap::Mode
画像形式を取得します.
-
#palette ⇒ Rixmap::Palette?
設定されているパレットを取得します.
-
#palette=(argPalette)
パレットを設定します.
-
#paste(argImage, argX, argY) ⇒ Rixmap::Image
この画像と指定された画像を合成した新しい画像を返します.
-
#paste!(argImage, argX, argY) ⇒ Rixmap::Image
別の画像をこの画像に破壊的に合成します.
-
#pixels ⇒ Array<Array>
この画像のすべてのピクセルデータを含む配列を返します.
-
#resize(width, height, anchor = nil) ⇒ Rixmap::Image
指定サイズに画像サイズを変更します.
-
#resize!(width, height, anchor = nil) ⇒ Rixmnap::Image
画像サイズを破壊的に変更します.
-
#rgb? ⇒ Boolean
この画像がRGBカラー形式かどうかを返します.
-
#rotate(angle) ⇒ Rixmap::Image
画像を回転させます.
-
#rotate!(angle) ⇒ Rixmap::Image
画像を破壊的に回転させます.
-
#scale(*args) ⇒ Object
画像を拡大または縮小します.
-
#scale!(*args) ⇒ Object
画像を破壊的に拡大または縮小します.
-
#size ⇒ Array<Integer>
画像サイズを配列で返します.
-
#split ⇒ Array<Rixmap::Image>
複数の色コンポーネントを含む画像を、各コンポーネント毎のグレースケール形式画像に分解します.
-
#transparent ⇒ Rixmap::Color, ...
透過色を取得します.
-
#transparent=(argColor)
透過色を設定します.
-
#width ⇒ Integer
画像の横幅を取得します.
Constructor Details
#initialize(mode, width, height, options = {}) (private)
新規画像を作成します.
1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 |
# File 'src/rixmapcore.cxx', line 1838
static VALUE Image_initialize(int argc, VALUE* argv, VALUE self) {
// 引数解析
VALUE argMode, argWidth, argHeight, argOptions;
rb_scan_args(argc, argv, "31", &argMode, &argWidth, &argHeight, &argOptions);
// オブジェクト -> 画像形式定数
Rixmap::Mode mode = Rixmap::Mode::NONE;
if (!RTEST(rb_obj_is_kind_of(argMode, cRixmapMode))) {
VALUE strMode = rb_funcall(rb_String(argMode), rb_intern("upcase"), 0);
std::string name(StringValueCStr(strMode));
mode = Rixmap::ModeInfo::GetModeByName(name);
} else {
Rixmap::ModeData* mdata = rixmap_unwrap<Rixmap::ModeData>(argMode);
mode = mdata->getMode();
}
// 画像サイズ
long width = NUM2LONG(argWidth);
long height = NUM2LONG(argHeight);
// データポインタを取得
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
try {
_this->init(mode, width, height);
} catch (const std::exception& e) {
rb_raise(rb_eArgError, e.what());
} catch (...) {
rb_raise(rb_eRuntimeError, "unknown error occurred");
}
// オプションパラメータを拾う
VALUE optPalette = Qnil;
VALUE optBackground = Qnil;
VALUE optTransparent = Qnil;
if (RB_TYPE_P(argOptions, T_HASH)) {
optPalette = rb_hash_lookup(argOptions, ID2SYM(rb_intern("palette")));
// TODO 型チェック
optBackground = rb_hash_lookup(argOptions, ID2SYM(rb_intern("background")));
optTransparent = rb_hash_lookup(argOptions, ID2SYM(rb_intern("transparent")));
}
// パレットの処置
if (_this->getModeInfo().isIndexedType() && NIL_P(optPalette)) {
// インデックスカラー形式でかつ、パレットが指定されてない場合は作る
optPalette = RixmapPalette_NewInstance(256);
}
// パレットの設定
_this->setPalette(optPalette);
// その他オプションパラメータ
Rixmap::Helper::SetBackgroundValue(*_this, _this->getBackground(), optBackground);
Rixmap::Helper::SetBackgroundValue(*_this, _this->getTransparent(), optTransparent);
// 背景色を反映
_this->clear();
// 戻る
return self;
}
|
Instance Method Details
#==(argObject) ⇒ Boolean
オブジェクトと比較して、同じ画像かどうかを返します.
2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 |
# File 'src/rixmapcore.cxx', line 2359
static VALUE Image_operatorEquals(VALUE self, VALUE argObject) {
if (self == argObject) {
// 自分自身はtrue
return Qtrue;
}
if (RTEST(rb_obj_is_kind_of(argObject, cRixmapImage))) {
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
Rixmap::ImageData* _that = rixmap_unwrap<Rixmap::ImageData>(argObject);
if (*_this == *_that) {
return Qtrue;
} else {
return Qfalse;
}
} else {
// クラスが違う場合はfalse
return Qfalse;
}
}
|
#[](lineno) ⇒ Rixmap::Image::Line #[](x, y) ⇒ Integer, ...
指定したスキャンラインまたはピクセルデータを取得します.
2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 |
# File 'src/rixmapcore.cxx', line 2156
static VALUE Image_offsetGet(int argc, VALUE* argv, VALUE self) {
// 引数を解析
VALUE arg0 = Qnil, arg1 = Qnil;
rb_scan_args(argc, argv, "11", &arg0, &arg1);
if (NIL_P(arg1)) {
// [line] 形式
// TODO [nil, nil] とかどうするよ
long lineno = NUM2LONG(rb_Integer(arg0));
return RixmapImageLine_NewInstance(self, lineno);
} else {
// [x, y] 形式ですよねー
// TODO [nil, 0] とかどうするよ
long xpos = NUM2LONG(rb_Integer(arg0));
long ypos = NUM2LONG(rb_Integer(arg1));
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
return Rixmap::Helper::GetPixel(_this, xpos, ypos);
}
}
|
#[]=(lineno, data) #[]=(x, y, data)
スキャンラインまたはピクセルを更新します.
2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 |
# File 'src/rixmapcore.cxx', line 2256
static VALUE Image_offsetSet(int argc, VALUE* argv, VALUE self) {
// 引数解析
VALUE arg0 = Qnil, arg1 = Qnil, arg2 = Qnil;
rb_scan_args(argc, argv, "21", &arg0, &arg1, &arg2);
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
const Rixmap::ModeInfo& mode = _this->getModeInfo();
VALUE argLineNumber = Qnil, argX = Qnil, argY = Qnil;
VALUE argData = Qnil;
if (NIL_P(arg2)) {
// [lineno] = data 形式
argLineNumber = arg0;
argData = arg1;
int32_t lineno = NUM2LONG(argLineNumber);
// 範囲チェック
if (_this->isInside(0, lineno)) {
// 引数チェック
if (RTEST(rb_obj_is_kind_of(argData, cRixmapBinary))) {
Rixmap::BinaryData* data = rixmap_unwrap<Rixmap::BinaryData>(argData);
int32_t dataLength = static_cast<int32_t>(data->size());
int32_t width = _this->getWidth();
const Rixmap::ChannelArray& channels = mode.getChannels();
int nchannel = channels.size();
int32_t maxLength = width * nchannel; // FIXME 場合によってはオーバーフロー
int32_t length = (dataLength < maxLength) ? dataLength : maxLength;
for (int32_t i = 0; i < length; i++) {
int32_t w = (i / nchannel);
int32_t c = (i % nchannel);
Rixmap::Channel channel = channels.at(c);
_this->set(channel, w, lineno, data->at(i));
}
} else if (RB_TYPE_P(argData, T_ARRAY)) {
// 配列なので、いったん全要素をチェックする
long nitem = RARRAY_LEN(argData);
int32_t width = _this->getWidth();
int32_t length = (width < nitem) ? width : nitem;
for (int32_t i = 0; i < length; i++) {
VALUE item = rb_ary_entry(argData, i);
if (RB_TYPE_P(item, T_FIXNUM) || RB_TYPE_P(item, T_ARRAY) || RTEST(rb_obj_is_kind_of(item, cRixmapColor))) {
} else {
rb_raise(rb_eArgError, "unexpected pixel data type in line data: %s", rb_obj_classname(item));
}
}
// 要素を更新
for (int32_t i = 0; i < length; i++) {
VALUE item = rb_ary_entry(argData, i);
Rixmap::Helper::UpdatePixel(_this, i, lineno, item);
}
} else if (RB_TYPE_P(argData, T_STRING)) {
// TODO rb_String使って強制的に文字列化する
// 文字列
long nbyte = RSTRING_LEN(argData);
const char* bytes = RSTRING_PTR(argData);
int32_t width = _this->getWidth();
const Rixmap::ChannelArray& channels = mode.getChannels();
int nchannel = channels.size();
int32_t maxlength = width * nchannel; // FIXME 場合によってはオーバーフローするよなぁこれ
int32_t length = (nbyte < maxlength) ? nbyte : maxlength;
for (int32_t i = 0; i < length; i++) {
int32_t w = (i / nchannel);
int32_t c = (i % nchannel);
Rixmap::Channel channel = channels.at(c);
_this->set(channel, w, lineno, bytes[i]);
}
} else {
// 非対応(´・ω・`)
rb_raise(rb_eArgError, "unexpected line data type: %s", rb_obj_classname(argData));
}
} else {
// 範囲外
rb_warning("line %d is outside of image", lineno);
}
} else {
// [x, y] = data 形式
argX = arg0;
argY = arg1;
argData = arg2;
// ネイティブ値へ
int32_t xpos = NUM2LONG(rb_Integer(argX));
int32_t ypos = NUM2LONG(rb_Integer(argY));
Rixmap::Helper::UpdatePixel(_this, xpos, ypos, argData);
}
// 戻る
return argData;
}
|
#background ⇒ Rixmap::Color, ...
背景色を取得します.
1979 1980 1981 1982 1983 1984 |
# File 'src/rixmapcore.cxx', line 1979
static VALUE Image_getBackground(VALUE self) {
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
Rixmap::BackgroundColor& _bg = _this->getBackground();
return Rixmap::Helper::GetBackgroundValue(*_this, _bg);
}
|
#background=(argColor)
This method returns an undefined value.
背景色を設定します.
1992 1993 1994 1995 1996 1997 |
# File 'src/rixmapcore.cxx', line 1992
static VALUE Image_setBackground(VALUE self, VALUE argColor) {
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
Rixmap::BackgroundColor& _bg = _this->getBackground();
Rixmap::Helper::SetBackgroundValue(*_this, _bg, argColor);
return argColor;
}
|
#convert(argMode) ⇒ Rixmap::Image
画像形式を変換します.
2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 |
# File 'src/rixmapcore.cxx', line 2517
static VALUE Image_convert(VALUE self, VALUE argMode) {
VALUE destImage = Qnil;
{
VALUE params[3] = {
argMode,
rb_funcall(self, rb_intern("width"), 0),
rb_funcall(self, rb_intern("height"), 0)
};
destImage = rb_class_new_instance(3, params, cRixmapImage);
}
// ポインタ
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
Rixmap::ImageData* _dest = rixmap_unwrap<Rixmap::ImageData>(destImage);
// コンバータ
try {
Rixmap::Converter* converter = Rixmap::Helper::GetImageConverter(_this->getMode(), _dest->getMode());
converter->convert(*_this, *_dest);
} catch (const std::exception& e) {
rb_raise(rb_eRuntimeError, e.what());
}
return destImage;
}
|
#crop(argLeft, argTop, argRight, argBottom) ⇒ Rixmap::Image
指定領域の部分画像を取得します.
2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 |
# File 'src/rixmapcore.cxx', line 2710
static VALUE Image_crop(VALUE self, VALUE argLeft, VALUE argTop, VALUE argRight, VALUE argBottom) {
// 自分
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
// 領域決定
int32_t left = NUM2LONG(rb_Integer(argLeft));
int32_t top = NUM2LONG(rb_Integer(argTop));
int32_t right = NUM2LONG(rb_Integer(argRight));
int32_t bottom = NUM2LONG(rb_Integer(argBottom));
// チェック
if (left >= right) {
rb_raise(rb_eArgError, "left edge is over right edge: %d < %d is not valid.", left, right);
}
if (top >= bottom) {
rb_raise(rb_eArgError, "top edge is over bottom edge: %d < %d is not valid.", top, bottom);
}
// 幅
int32_t newWidth = (right - left) + 1;
int32_t newHeight = (bottom - top) + 1;
// 適用先
VALUE cropOptions = Rixmap::Helper::GetImageMetadata(*_this);
VALUE croppedImage = RixmapImage_NewInstance(_this->getMode(), newWidth, newHeight, cropOptions);
Rixmap::ImageData* cropped = rixmap_unwrap<Rixmap::ImageData>(croppedImage);
// ピクセルを切り出し
int32_t selfWidth = _this->getWidth();
int32_t selfHeight = _this->getHeight();
const Rixmap::ChannelArray& channels = _this->getModeInfo().getChannels();
for (auto it = channels.begin(); it != channels.end(); it++) {
Rixmap::Channel channel = *it;
for (int32_t h = top; h <= bottom; h++) {
if (h < 0 || selfHeight <= h) {
continue;
}
for (int32_t w = left; w <= right; w++) {
if (w < 0 || selfWidth <= w) {
continue;
}
cropped->set(channel, (w - left), (h - top), _this->get(channel, w, h));
}
}
}
// 複製を戻す
return croppedImage;
}
|
#crop!(argLeft, argTop, argRight, argBottom) ⇒ Rixmap::Image
この画像を指定領域の部分画像に切り詰めます. オブジェクト自体を破壊的に変更します.
2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 |
# File 'src/rixmapcore.cxx', line 2685
static VALUE Image_cropSelf(VALUE self, VALUE argLeft, VALUE argTop, VALUE argRight, VALUE argBottom) {
// 自分
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
// 複製を取得
VALUE croppedImage = rb_funcall(self, rb_intern("crop"), 4, argLeft, argTop, argRight, argBottom);
// 自分へ移動
Rixmap::ImageData* cropped = rixmap_unwrap<Rixmap::ImageData>(croppedImage);
*_this = *cropped;
// 自分を戻す
return self;
}
|
#deform(deformer, *args) ⇒ Rixmap::Image
2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 |
# File 'src/rixmapcore.cxx', line 2812
static VALUE Image_deform(int argc, VALUE* argv, VALUE self) {
VALUE argDeformer, argParams;
rb_scan_args(argc, argv, "1*", &argDeformer, &argParams);
// パラメータを構築
VALUE params = rb_ary_new();
rb_ary_push(params, self);
rb_ary_concat(params, argParams);
// 変形実行
VALUE deformed = rb_funcall2(argDeformer, rb_intern("deform"), RARRAY_LEN(params), RARRAY_PTR(params));
// 変形画像を返却
return deformed;
}
|
#deform!(deformer, *args) ⇒ Rixmap::Image
2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 |
# File 'src/rixmapcore.cxx', line 2837
static VALUE Image_deformSelf(int argc, VALUE* argv, VALUE self) {
VALUE argDeformer, argParams;
rb_scan_args(argc, argv, "1*", &argDeformer, &argParams);
// パラメータを構築
VALUE params = rb_ary_new();
rb_ary_push(params, self);
rb_ary_concat(params, argParams);
// 変形実行
VALUE deformedImage = rb_funcall2(argDeformer, rb_intern("deform"), RARRAY_LEN(params), RARRAY_PTR(params));
// 自分に上書き
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
Rixmap::ImageData* deformed = rixmap_unwrap<Rixmap::ImageData>(deformedImage);
*_this = *deformed;
return self;
}
|
#dimension ⇒ Array<Integer>
画像の寸法を配列で返します.
寸法には
- 横幅
- 高さ
- チャンネル数
が含まれます.
2052 2053 2054 2055 2056 2057 2058 2059 2060 |
# File 'src/rixmapcore.cxx', line 2052
static VALUE Image_getDimension(VALUE self) {
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
VALUE objDim = rb_ary_new2(3);
rb_ary_store(objDim, 0, LONG2NUM(_this->getWidth()));
rb_ary_store(objDim, 1, LONG2NUM(_this->getHeight()));
rb_ary_store(objDim, 2, INT2FIX(_this->getModeInfo().getChannels().size()));
OBJ_FREEZE(objDim);
return objDim;
}
|
#each_line ⇒ Enumerator #each_line {|line| ... }
スキャンライン走査するイテレータを返します. ブロックが渡されている場合は各スキャンラインを引数としてブロックを呼び出します.
2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 |
# File 'src/rixmapcore.cxx', line 2392
static VALUE Image_eachLine(VALUE self) {
if (rb_block_given_p()) { // ブロック有
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
for (int32_t h = 0; h < _this->getHeight(); h++) {
VALUE line = RixmapImageLine_NewInstance(self, h);
rb_yield_values(1, line);
}
return self;
} else { // ブロック無
// TODO サイズ計算関数の追加
// その時は rb_enumeratorize_with_sizeを使おう
// (RETURN_SIZED_ENUMERATORでもいいかも)
return rb_enumeratorize(self, ID2SYM(rb_frame_this_func()), 0, NULL);
}
}
|
#each_pixel ⇒ Enumerator #each_pixel {|pixel| ... }
ピクセルを走査するイテレータを返します. ブロックが渡されている場合は各ピクセルを引数としてブロックを呼び出します.
ピクセルの走査は左上から右下へ、スキャンラインを左から右へ向かって行います.
2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 |
# File 'src/rixmapcore.cxx', line 2422
static VALUE Image_eachPixel(VALUE self) {
if (rb_block_given_p()) { // ブロック有
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
for (int32_t h = 0; h < _this->getHeight(); h++) {
for (int32_t w = 0; w < _this->getWidth(); w++) {
VALUE pixel = Rixmap::Helper::GetPixel(_this, w, h);
rb_yield_values(1, pixel);
}
}
return self;
} else { // ブロック無
// TODO サイズ計算関数の追加
// その時は rb_enumeratorize_with_sizeを使おう
// (RETURN_SIZED_ENUMERATORでもいいかも)
return rb_enumeratorize(self, ID2SYM(rb_frame_this_func()), 0, NULL);
}
}
|
#fill(*args) ⇒ Object
指定色で塗りつぶした画像を返します.
2668 2669 2670 2671 2672 |
# File 'src/rixmapcore.cxx', line 2668
static VALUE Image_fill(int argc, VALUE* argv, VALUE self) {
VALUE image = rb_obj_clone(self);
rb_funcall2(image, rb_intern("fill!"), argc, argv);
return image;
}
|
#fill!(color) ⇒ Rixmap::Image #fill!(color, left, top, right, bottom) ⇒ Rixmap::Image
画像を指定色で破壊的に塗りつぶします.
2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 |
# File 'src/rixmapcore.cxx', line 2608
static VALUE Image_fillSelf(int argc, VALUE* argv, VALUE self) {
VALUE argColor = Qnil;
// 領域
int32_t left = 0, top = 0, right = 0, bottom = 0;
// 自分
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
switch (argc) {
case 1: // fill!(color)
argColor = argv[0];
left = 0;
top = 0;
right = _this->getWidth() - 1;
bottom = _this->getHeight() - 1;
break;
case 5: // fille!(color, left, top, right, bottom)
argColor = argv[0];
left = NUM2LONG(rb_Integer(argv[1]));
top = NUM2LONG(rb_Integer(argv[2]));
right = NUM2LONG(rb_Integer(argv[3]));
bottom = NUM2LONG(rb_Integer(argv[4]));
// 補正
if (left < 0) {
left = 0;
}
if (top < 0) {
top = 0;
}
if (right >= _this->getWidth()) {
right = _this->getWidth() - 1;
}
if (bottom >= _this->getHeight()) {
bottom = _this->getHeight() - 1;
}
break;
default:
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 5)", argc);
break;
}
// 更新
for (int32_t h = top; h <= bottom; h++) {
for (int32_t w = left; w <= right; w++) {
Rixmap::Helper::UpdatePixel(_this, w, h, argColor);
}
}
return self;
}
|
#flip(argDirection) ⇒ Rixmap::Image
指定方向に反転を行った画像を返します.
2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 |
# File 'src/rixmapcore.cxx', line 2881
static VALUE Image_flip(VALUE self, VALUE argDirection) {
// 複製を作成
VALUE image = rb_obj_clone(self);
// 複製を反転
rb_funcall(image, rb_intern("flip!"), 1, argDirection);
// 複製を戻す
return image;
}
|
#flip!(argDirection) ⇒ Rixmap::Image
指定方向に破壊的に反転処理を行います.
2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 |
# File 'src/rixmapcore.cxx', line 2863
static VALUE Image_flipSelf(VALUE self, VALUE argDirection) {
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
// 反転方向
Rixmap::FlipDirection direction = static_cast<Rixmap::FlipDirection>(NUM2INT(rb_Integer(argDirection)));
// 反転処理
_this->flip(direction);
return self;
}
|
#get_bounds(width, height, anchor) ⇒ Array<Integer> (private)
#resize用にanchor
から[left, top, right, bottom]形式の配列を作成します.
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/rixmap/image.rb', line 150 def get_bounds(width, height, anchor) left = 0 top = 0 right = 0 bottom = 0 if anchor.nil? anchor = :nw else anchor = anchor.to_s.downcase.to_sym end case anchor when :n, :north left = (self.width / 2.0 - width / 2.0).floor right = left + width - 1 top = 0 bottom = height - 1 when :nw, :northwest left = 0 top = 0 right = width - 1 bottom = height - 1 when :ne, :northeast left = self.width - width top = 0 right = self.width - 1 bottom = height - 1 when :w, :west left = 0 top = (self.height / 2.0 - height / 2.0).floor right = width - 1 bottom = top + height - 1 when :c, :center left = (self.width / 2.0 - width / 2.0).floor top = (self.height / 2.0 - height / 2.0).floor right = left + width - 1 bottom = top + height - 1 when :e, :east left = self.width - width top = (self.height / 2.0 - height / 2.0).floor right = self.width - 1 bottom = top + height - 1 when :s, :south left = (self.width / 2.0 - width / 2.0).floor top = (self.height - height) right = left + width - 1 bottom = self.height - 1 when :sw, :southwest left = 0 top = (self.height - height) right = width - 1 bottom = self.height - 1 when :se, :southeast left = self.width - width top = self.height - height right = self.width - 1 bottom = self.height - 1 else raise ArgumentError.new("Unsupported Resize-Anchor: #{anchor}") end return [left, top, right, bottom] end |
#grayscale? ⇒ Boolean
この画像がグレースケール形式かどうかを返します.
2083 2084 2085 2086 2087 2088 2089 2090 |
# File 'src/rixmapcore.cxx', line 2083
static VALUE Image_isGrayScaleImage(VALUE self) {
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
if (_this->getModeInfo().isGrayScaleType()) {
return Qtrue;
} else {
return Qfalse;
}
}
|
#has_alpha? ⇒ Boolean
この画像が透明度を持っているかを返します.
2113 2114 2115 2116 2117 2118 2119 2120 |
# File 'src/rixmapcore.cxx', line 2113
static VALUE Image_hasAlphaChannel(VALUE self) {
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
if (_this->getModeInfo().hasAlpha()) {
return Qtrue;
} else {
return Qfalse;
}
}
|
#height ⇒ Integer
画像の高さを取得します.
1941 1942 1943 1944 |
# File 'src/rixmapcore.cxx', line 1941
static VALUE Image_getHeight(VALUE self) {
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
return LONG2NUM(_this->getHeight());
}
|
#indexed? ⇒ Boolean
この画像がインデックスカラー形式かどうかを返します.
2068 2069 2070 2071 2072 2073 2074 2075 |
# File 'src/rixmapcore.cxx', line 2068
static VALUE Image_isIndexedImage(VALUE self) {
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
if (_this->getModeInfo().isIndexedType()) {
return Qtrue;
} else {
return Qfalse;
}
}
|
#initialize_copy(argObject) (private)
This method returns an undefined value.
複製されたオブジェクトを初期化します.
1906 1907 1908 1909 1910 1911 1912 1913 1914 |
# File 'src/rixmapcore.cxx', line 1906
static VALUE Image_initializeCopy(VALUE self, VALUE argObject) {
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
Rixmap::ImageData* _that = rixmap_unwrap<Rixmap::ImageData>(argObject);
// 複製
*_this = *_that;
return self;
}
|
#inspect ⇒ String
オブジェクトとしての文字列表現を返します.
2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 |
# File 'src/rixmapcore.cxx', line 2489
static VALUE Image_inspect(VALUE self) {
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
volatile VALUE objPalette = _this->getPalette();
volatile VALUE objBackground = Rixmap::Helper::GetBackgroundValue(*_this, _this->getBackground());
volatile VALUE objTransparent = Rixmap::Helper::GetBackgroundValue(*_this, _this->getTransparent());
volatile VALUE paletteText = rb_inspect(objPalette);
volatile VALUE backgroundText = rb_inspect(objBackground);
volatile VALUE transparentText = rb_inspect(objTransparent);
return rb_enc_sprintf(
rb_usascii_encoding(),
"#<%s:%p mode=%s, size=(%d, %d), palette=%s, background=%s, transparent=%s>",
//"#<%s:%p mode=%s, size=(%d, %d), palette=%s>",
rb_obj_classname(self), reinterpret_cast<void*>(self),
_this->getModeInfo().getName().c_str(),
_this->getWidth(),
_this->getHeight(),
StringValueCStr(paletteText),
StringValueCStr(backgroundText),
StringValueCStr(transparentText)
);
}
|
#lines ⇒ Array<Rixmap::Image::Line>
この画像の全てのスキャンラインを含む配列を返します.
2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 |
# File 'src/rixmapcore.cxx', line 2446
static VALUE Image_getLines(VALUE self) {
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
VALUE aryLines = rb_ary_new2(_this->getHeight());
for (int32_t h = 0; h < _this->getHeight(); h++) {
VALUE line = RixmapImageLine_NewInstance(self, h);
rb_ary_store(aryLines, h, line);
}
return aryLines;
}
|
#mode ⇒ Rixmap::Mode
画像形式を取得します.
1921 1922 1923 1924 |
# File 'src/rixmapcore.cxx', line 1921
static VALUE Image_getMode(VALUE self) {
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
return RixmapModePool::Get(_this->getMode());
}
|
#palette ⇒ Rixmap::Palette?
設定されているパレットを取得します.
1951 1952 1953 1954 |
# File 'src/rixmapcore.cxx', line 1951
static VALUE Image_getPalette(VALUE self) {
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
return _this->getPalette();
}
|
#palette=(argPalette)
This method returns an undefined value.
パレットを設定します.
1962 1963 1964 1965 1966 1967 1968 1969 1970 |
# File 'src/rixmapcore.cxx', line 1962
static VALUE Image_setPalette(VALUE self, VALUE argPalette) {
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
if (RTEST(rb_obj_is_kind_of(argPalette, cRixmapPalette))) {
_this->setPalette(argPalette);
} else {
rb_raise(rb_eArgError, "palette expected %s, but %s", rb_class2name(cRixmapPalette), rb_obj_classname(argPalette));
}
return argPalette;
}
|
#paste(argImage, argX, argY) ⇒ Rixmap::Image
この画像と指定された画像を合成した新しい画像を返します.
2798 2799 2800 2801 |
# File 'src/rixmapcore.cxx', line 2798
static VALUE Image_paste(VALUE self, VALUE argImage, VALUE argX, VALUE argY) {
VALUE base = rb_obj_clone(self);
return rb_funcall(base, rb_intern("paste!"), 3, argImage, argX, argY);
}
|
#paste!(argImage, argX, argY) ⇒ Rixmap::Image
別の画像をこの画像に破壊的に合成します.
2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 |
# File 'src/rixmapcore.cxx', line 2769
static VALUE Image_pasteSelf(VALUE self, VALUE argImage, VALUE argX, VALUE argY) {
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
Rixmap::ImageData* image = rixmap_unwrap<Rixmap::ImageData>(argImage);
int32_t xoffset = NUM2LONG(rb_Integer(argX));
int32_t yoffset = NUM2LONG(rb_Integer(argY));
for (int32_t h = 0; h < image->getHeight(); h++) {
for (int32_t w = 0; w < image->getWidth(); w++) {
int32_t xpos = xoffset + w;
int32_t ypos = yoffset + h;
if (_this->isInside(xpos, ypos)) {
Rixmap::Color pixel = image->fetch(w, h);
Rixmap::Helper::UpdatePixel(_this, xpos, ypos, RixmapColorPool::Get(pixel));
}
}
}
return self;
}
|
#pixels ⇒ Array<Array>
この画像のすべてのピクセルデータを含む配列を返します.
ピクセルデータはスキャンラインごとに入れ子の配列になります.
2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 |
# File 'src/rixmapcore.cxx', line 2467
static VALUE Image_getPixels(VALUE self) {
// TODO NArrayがある場合はそっちを使いたいねぇ
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
VALUE aryPixels = rb_ary_new2(_this->getHeight());
for (int32_t h = 0; h < _this->getHeight(); h++) {
VALUE aryLine = rb_ary_new2(_this->getWidth());
for (int32_t w = 0; w < _this->getWidth(); w++) {
VALUE pixel = Rixmap::Helper::GetPixel(_this, w, h);
rb_ary_store(aryLine, w, pixel);
}
rb_ary_store(aryPixels, h, aryLine);
}
return aryPixels;
}
|
#resize(width, height, anchor = nil) ⇒ Rixmap::Image
指定サイズに画像サイズを変更します.
ピクセルは拡縮されないことに注意してください. あくまで、画像自体のサイズ変更を目的としています.
38 39 40 41 |
# File 'lib/rixmap/image.rb', line 38 def resize(width, height, anchor=nil) left, top, right, bottom = get_bounds(width, height, anchor) return self.crop(left, top, right, bottom) end |
#resize!(width, height, anchor = nil) ⇒ Rixmnap::Image
画像サイズを破壊的に変更します.
51 52 53 54 |
# File 'lib/rixmap/image.rb', line 51 def resize!(width, height, anchor=nil) left, top, right, bottom = get_bounds(width, height, anchor) return self.crop!(left, top, right, bottom) end |
#rgb? ⇒ Boolean
この画像がRGBカラー形式かどうかを返します.
2098 2099 2100 2101 2102 2103 2104 2105 |
# File 'src/rixmapcore.cxx', line 2098
static VALUE Image_isRGBImage(VALUE self) {
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
if (_this->getModeInfo().isRGBType()) {
return Qtrue;
} else {
return Qfalse;
}
}
|
#rotate(angle) ⇒ Rixmap::Image
画像を回転させます.
126 127 128 129 130 131 |
# File 'lib/rixmap/image.rb', line 126 def rotate(angle) deformer = Rixmap::Deformer::AffineDeformer.new deformer.matrix.angle = angle deformer.interpolator = Rixmap::Deformer::IPO_BICUBIC return self.deform(deformer, true) end |
#rotate!(angle) ⇒ Rixmap::Image
画像を破壊的に回転させます.
137 138 139 140 141 142 |
# File 'lib/rixmap/image.rb', line 137 def rotate!(angle) deformer = Rixmap::Deformer::AffineDeformer.new deformer.matrix.angle = angle deformer.interpolator = Rixmap::Deformer::IPO_BICUBIC return self.deform!(deformer, true) end |
#scale(scale) ⇒ Rixmap::Image #scale(xscale, yscale) ⇒ Rixmap::Image
画像を拡大または縮小します.
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/rixmap/image.rb', line 68 def scale(*args) xscale = 1.0 yscale = 1.0 case args.size when 1 xscale = args[0].to_f yscale = args[0].to_f when 2 xscale = args[0].to_f yscale = args[1].to_f else raise ArgumentError.new("wrong number of arguments (#{args.size} for 1..2)") end deformer = Rixmap::Deformer::AffineDeformer.new deformer.matrix.scale = [xscale, yscale] return self.deform(deformer, true) end |
#scale(scale) ⇒ Rixmap::Image #scale(xscale, yscale) ⇒ Rixmap::Image
画像を破壊的に拡大または縮小します.
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/rixmap/image.rb', line 101 def scale!(*args) xscale = 1.0 yscale = 1.0 case args.size when 1 xscale = args[0].to_f yscale = args[0].to_f when 2 xscale = args[0].to_f yscale = args[1].to_f else raise ArgumentError.new("wrong number of arguments (#{args.size} for 1..2)") end deformer = Rixmap::Deformer::AffineDeformer.new deformer.matrix.scale = [xscale, yscale] return self.deform!(deformer, true) end |
#size ⇒ Array<Integer>
画像サイズを配列で返します.
2029 2030 2031 2032 2033 2034 2035 2036 |
# File 'src/rixmapcore.cxx', line 2029
static VALUE Image_getSize(VALUE self) {
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
VALUE objSize = rb_ary_new2(2);
rb_ary_store(objSize, 0, LONG2NUM(_this->getWidth()));
rb_ary_store(objSize, 1, LONG2NUM(_this->getHeight()));
OBJ_FREEZE(objSize);
return objSize;
}
|
#split ⇒ Array<Rixmap::Image>
複数の色コンポーネントを含む画像を、各コンポーネント毎のグレースケール形式画像に分解します.
変換ルールとしてはインデックスカラー形式のみ、そのまま返されます.
それ以外はR
, G
, B
, L
, A
の各色のみを含むグレースケール形式になります.
2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 |
# File 'src/rixmapcore.cxx', line 2551
static VALUE Image_split(VALUE self) {
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
const Rixmap::ModeInfo& _mode = _this->getModeInfo();
VALUE planes = rb_ary_new();
if (_mode.isIndexedType()) {
rb_ary_push(planes, self);
} else {
int32_t _width = _this->getWidth();
int32_t _height = _this->getHeight();
const Rixmap::ChannelArray& _channels = _mode.getChannels();
for (auto it = _channels.begin(); it != _channels.end(); it++) {
Rixmap::Channel channel = *it;
// グレースケール画像を作成
VALUE plane = RixmapImage_NewInstance(Rixmap::Mode::GRAYSCALE, _width, _height);
Rixmap::ImageData* data = rixmap_unwrap<Rixmap::ImageData>(plane);
for (int32_t h = 0; h < _height; h++) {
for (int32_t w = 0; w < _width; w++) {
data->set(Rixmap::Channel::LUMINANCE, w, h, _this->get(channel, w, h));
}
}
rb_ary_push(planes, plane);
}
}
return planes;
}
|
#transparent ⇒ Rixmap::Color, ...
透過色を取得します.
2005 2006 2007 2008 2009 |
# File 'src/rixmapcore.cxx', line 2005
static VALUE Image_getTransparent(VALUE self) {
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
Rixmap::BackgroundColor& _trans = _this->getTransparent();
return Rixmap::Helper::GetBackgroundValue(*_this, _trans);
}
|
#transparent=(argColor)
This method returns an undefined value.
透過色を設定します.
2017 2018 2019 2020 2021 2022 |
# File 'src/rixmapcore.cxx', line 2017
static VALUE Image_setTransparent(VALUE self, VALUE argColor) {
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
Rixmap::BackgroundColor& _trans = _this->getTransparent();
Rixmap::Helper::SetBackgroundValue(*_this, _trans, argColor);
return argColor;
}
|
#width ⇒ Integer
画像の横幅を取得します.
1931 1932 1933 1934 |
# File 'src/rixmapcore.cxx', line 1931
static VALUE Image_getWidth(VALUE self) {
Rixmap::ImageData* _this = rixmap_unwrap<Rixmap::ImageData>(self);
return LONG2NUM(_this->getWidth());
}
|