GIL팳̼/h1>
׷՟:
Lubomir Bourdev (lbourdev@adobe.com) and Hailin Jin (hljin@adobe.com)
Adobe ϵͳ髖dd>
঱/b>
2.1
ȕƚ:
September 15, 2007
GILʇһ趴Ӌ㷨퇶ȳ錚ͼϱ퓿ڵă++ꯊ,GILԲٗݖր෱栵č쏱豊膤ĜԺ͕붔ij֖̘樍쏱豊ʖ亂돠懃.

ᾎĵ劇ʹӃGIL儒븶﬋نൣ,բ/uӐ̖›GIL儵ײ㉨솼/span>,Ҳ⻊ǒ븶GIL䳈뼯span>,ģԔڼ/span>GIL監獸վՒ彸쏪ϸ儐ŏ⼯span> http://opensource.adobe.com/gil

ಗ༯a>

GIL׮Ђ঱ҔԚGIL͸վςԘ http://opensource.adobe.com/gil. GILґ㺋ͨ齼ӈ뢯ost,伴拊boostһưಗK http://www.boost.org. GIL 溺ꬍ玄쾬⢲됨ҪȎꎵā體Ҳ⻐蒪鹽襏ost. 攓ھ貰櫳餳̀䋵,༺썷΄쾠boost/gil/gil_all.hpp 촿ɮ

ʾ=-솋㍼ϱ̝卯/a>

᾽̳̽밑ʹӃGIL솋㍼ϱ̝戟Ċ顴銼֕.ΒCӒ됩照㼲婗ķǷ껯儴ꂫ慠쬖ཥʹ֮轀ӵķ껯.ΒC䓼Ƌ㋮ƽ̝房ꊼ,⢇Ҋ鈴׮첵嵄̝戔㷨-֐Є⮋㷨.Ҫ솋㔚ˮƽλփx粲ዘ̝戩ʹӃ髊D[x] = (I[x-1] - I[x+1]) / 2

ΪK첻﬎҃Ǻ悔K៽燩ﶭ攓ڍ쏱儱߽絣ϱ˘澠ԬƤZʇ⻴攚儮ᾎĵĖص八ȧꎊ鈴GIL,渲늇һ趺oČݶȋ㷨.

퓿ں͕㺏亂뼯a>

ΒCˣ滋Ċ䈫ʇһ躉λΞ綹ŻҶȍ쏱, ʤ㶊ǒ븶8λӐ綹ŻҶȍ쏱, ˣ滋Ľӿڈ珂˹ʾ:

#include <boost/gil/gil_all.hpp>
using namespace boost::gil;

void x_gradient(const gray8c_view_t& src, const gray8s_view_t& dst) {
    assert(src.dimensions() == dst.dimensions());
    ...    // 솋㌝卯/span>
}

gray8c_view_t ʇһ躉λ뒶ȍ쏱ʓͼ Ѝ,ϱ˘ʇֻ惠ĨʹӃ綹żcode>"c"ᭃ穬ʤ㶵ĀЍʇ8λӐ綹ŕ됍ֵ儻Ҷȍ쨊鈴"s"ᭃ穮 轂챊LJILʵ̥ ЍuuԼ樵Ē븶ͪջeʶ

GIL 豇跖ͼϱꍼem>ͼϱʓͼ儸ń븶GIL ͼϱʓͼ, ʇһ趹ؓھؐθ፸ϱ˘쯺ϵć㲣,ǡ춵ĊӍ쮋쌡驁ˏዘ烎ʽӿڬ嫊DzⲻӵӐբϱ˘.ʓͼ兒鷫첢⻖䐐ϱ˘儉ア䮍쏱ʓͼהɭ儳̘⻻ᴫ⥸荼ϱϱ˘,Ҳ渶ԍ쏱ʓͼלӦ胒ԳҽӃ儐Ί특Ӄ.䵄빊ǖ북儊NJӍ쀠Ѝ儒븶ʴ.

GIL ͼϱ,ʇһ֖ӵӐ˹ӐȨ儊Ӎ쮠˼ʇϱ˘儈݆紼쵄鷫쯎湹롷օ䯊ͷŏዘ.˼兒鷫컡ִϱ˘儉ア䬆䲙׷綻=롖ึሽϏዘֵ.ͼϱ儳Ѝ롴뵝踏ዘ-һ足ҽӃ傻쏱⻔ʐ퐞脆䏱˘ֵ.

㶠ʽ儠GIL ˣ稊NJ鼓Ԛͼϱʓͼɏ靚쫉ٓٗݍ쏱ᾉ.GIL儉輆-ĮꍓTL쫆䏠ˆ.GILͼϱ攓據STL/儈݆笀툧std::vector, 渠GIL's ͼϱʓͼ攓ړTL/a儇輤,STLĚ儇輤㣳㱭ϖΪһ촺Ʒ.STLˣ稗瓃ԚǸ줖,բսȧGILˣ稗瓃Ԛͼϱʓͼɏһѹ.

GIL傻쏱ʓͼԴӔ퉺ʽ錟-ά戩yʽėֽڊO蕫᭏ֵĊ﩮ςaʇһ摑ӄ㵄亂뵽GIL儕㺏亂뺼p>

void ComputeXGradientGray8(const unsigned char* src_pixels, ptrdiff_t src_row_bytes, int w, int h,
                                   signed char* dst_pixels, ptrdiff_t dst_row_bytes) {
    gray8c_view_t src = interleaved_view(w, h, (const gray8_pixel_t*)src_pixels,src_row_bytes);
    gray8s_view_t dst = interleaved_view(w, h, (     gray8s_pixel_t*)dst_pixels,dst_row_bytes);
    x_gradient(src,dst);
}

բ掕㺏亂닙戺ܿ쬊Ӎ야Ӄ儷ϺҲ꜐ᭉσ抾=֐y越Ӎ습=ֻӐ16趗ֽڬ༺쒻趗㉏罏ዘָիꍈջʽ-ﭬ蟺̓ז횊h3> 麼봎ʵϖ

ΒCѽ鵣煔ڼⵥ兗Njٶȉσ欼Ƌ㋮ƽ̝戟ċ㷨ȧς:

void x_gradient(const gray8c_view_t& src, const gray8s_view_t& dst) {
    for (int y=0; y<src.height(); ++y)
        for (int x=1; x<src.width()-1; ++x)
            dst(x,y) = (src(x-1,y) - src(x+1,y)) / 2;
}

ΒCʹӃʓͼ儲ٗ緻ꯊerator(x,y)뱵o趨λփ粲ዘֵҽӃ,⢇Ұ䗳ӒZ儒밫賸笙. operator() 絻ؒ븶뒶ȏዘ儒퓃.뒶ȏዘֵԗ껻Ϊ攓淨ѕɫͨ倀Ѝ (src攓淨ʇunsigned char),⢇ҿɒԴӍ貲ֵ鷫쨕▻攻ҶȏዘӐ). ɏa儴ꂫȝҗ-嫊Dzⲻ蟐笒⎪澔겙׷綆operator() Ԛһ趶豍薐솋㏱˘載떃,բ롒톰쓷躍㋷貙׷,ςaʇһ躉쿬儰汾:

void x_gradient(const gray8c_view_t& src, const gray8s_view_t& dst) {
    for (int y=0; y<src.height(); ++y) {
        gray8c_view_t::x_iterator src_it = src.row_begin(y);
        gray8s_view_t::x_iterator dst_it = dst.row_begin(y);

        for (int x=1; x<src.width()-1; ++x)
            dst_it[x] = (src_it[x-1] - src_it[x+1]) / 2;
    }
}

攓ڃʽ쎒C漊鈴弴ꆷ㬇IL儵촺Ʒʇ˦뺷Iʵ촺Ʒᣈ繻ģ攋浟烎ʵ촺Ʒ⻊쏤㬄ǃ䄣ԈώꋼCǖ蕫. ʵ슔ډσ淨=ד֐,}趖蕫儀Ѝ漊ǃʽ儂㖸ի,⢇Ҳٗ緻 operator[] ̡驛싙監蕫˷ҽ♗箼p> 솋㴹ֱ罏⌝戟Ĵꂫꍋ罏ⵄ꜀ˆ:

void y_gradient(const gray8c_view_t& src, const gray8s_view_t& dst) {
    for (int x=0; x<src.width(); ++x) {
        gray8c_view_t::y_iterator src_it = src.col_begin(x);
        gray8s_view_t::y_iterator dst_it = dst.col_begin(x);

        for (int y=1; y<src.height()-1; ++y)
            dst_it[y] = (src_it[y-1] - src_it[y+1])/2;
    }
}

⻊Ǒ,淵ǑP,촴包һ趼code>y_iterator Ѝ儊啥, 鏲弴ꮠP弴겻Ĝ첵嵄ʹӃָի,ҲΪϠZϱ˘֮줵ľ+ʇͼϱһʽėֽڊILԚբ/ʹӃKһ躉ז횲儵촺Ʒ-༺쒻趁㖸իꍒ븶⽳䮠˼儲ٗ緻operator[] ʇ㋒Բ솋㋷ҽ.

ɏa儋㷨ʵϖy_iterator, 롱Ƞx_iterator ½Ꜷ਺܈ݒ״ﵽһ越큿충.բʇӉӚĚ䦷IʵĄ㊽ҽư靚ҲΪբ֖ģʽ弖′儻괦Ξ. Ѷԁđ煔ڄڲכּᲺɺһ趻괦ӑꃬ蟐纜栵İ汾:

void y_gradient(const gray8c_view_t& src, const gray8s_view_t& dst) {
    for (int y=1; y<src.height()-1; ++y) {
        gray8c_view_t::x_iterator src1_it = src.row_begin(y-1);
        gray8c_view_t::x_iterator src2_it = src.row_begin(y+1);
        gray8s_view_t::x_iterator dst_it = dst.row_begin(y);

        for (int x=0; x<src.width(); ++x) {
            *dst_it = ((*src1_it) - (*src2_it))/2;
            ++dst_it;
            ++src1_it;
            ++src2_it;
        }
    }
}

ɏa儴ꂫ빱탷K, 弴ꆷ儀ۼӺ͌ၬ♗翉Ҕ̦뻊鈴♗緻 operator[] .

ʹӃ樎놷

⻐ҵĊǬɏaբ趻괦ӑꃵİ汾Ҫ攔䊓ͼά뤁態ⵄ弴ꆷ. 攓ڃ︶ϱ˘,ΒCϣͻ烎ʆ䉏ςZ淵⿉Ҕͨ齇IL樎놷ʵϖ:

void y_gradient(const gray8c_view_t& src, const gray8s_view_t& dst) {
    gray8c_view_t::xy_locator src_loc = src.xy_at(0,1);
    for (int y=1; y<src.height()-1; ++y) {
        gray8s_view_t::x_iterator dst_it  = dst.row_begin(y);

        for (int x=0; x<src.width(); ++x) {
            (*dst_it) = (src_loc(0,-1) - src_loc(0,1)) / 2;
            ++dst_it;
            ++src_loc.x();                  // each dimension can be advanced separately
        }
        src_loc+=point2<std::ptrdiff_t>(-src.width(),1);    // carriage return
    }
}

麼됐亂봴˒븶樎놷,ָϲԴʓͼ儵ڶ儵ڒ븶ϱ˘.GILϱ˘樎놷㽁˄ܹ딚乖ẍˮƽ}趷폲漿ɒԒƶ͢,Ƥ˻儐Ў꺍弴ꆷ꜀ˆ. src_loc.x() ꍠsrc_loc.y() 皰෵똒븶乖ẍˮƽ罏ⵄ弴ꆷ,⢿ɒԑؗŏ㍻儷폲҆毬͉σ淨亂뒻ѹ. ͬʱ,ʹӃ♗緻 operator+= operator-=빿ɒԔځ罏≏ͬʱ҆毮 ꍍ쏱ʓͼ ˆ, 樎놷̡驁˶ֆ♗緻 operator() 絻ؖ趨λփ粲ዘҽӃ.=ȧ,src_loc(0,1) 絻صᇰϱ˘乖᷽ϲ粲’븶ϱ˘.樎놷ʇǡ춵Ķԏ㭉σ淨ʵ=֐樎놷ֻӐ8趗ֽڭ༺쁋һ趖菲屇λփ儂㖸ի,һ趴ӵᇰ彏’됐儆뒆ז횕됍ʽֵ(乖ᒆ毿ĊẲҪբ越햵). 巔ucode>++src_loc.x() ֻʇ奸驚햸ի儀ۼӲٗ箵늇ɏa儴ꂫ˹儲뱘Ҫ儼Ƌ㮠亂렼code>src_loc(0,1) ⻵o뼆ˣϱ˘Ԛ}趎춈ɏ儆뒆,բ롱ȽςעҢ螭빜ϱ˘載떃ȧꎬɏςZĎ떃ʇ⻱䵄. ΪK̡蟐Ԅܬ GIL Ի괦⢇ҖؓO⸶ƫֵ҆:

void y_gradient(const gray8c_view_t& src, const gray8s_view_t& dst) {
    gray8c_view_t::xy_locator src_loc = src.xy_at(0,1);
    gray8c_view_t::xy_locator::cached_location_t above = src_loc.cache_location(0,-1);
    gray8c_view_t::xy_locator::cached_location_t below = src_loc.cache_location(0, 1);

    for (int y=1; y<src.height()-1; ++y) {
        gray8s_view_t::x_iterator dst_it = dst.row_begin(y);

        for (int x=0; x<src.width(); ++x) {
            (*dst_it) = (src_loc[above] - src_loc[below])/2;
            ++dst_it;
            ++src_loc.x();             
        }
        src_loc+=point2<std::ptrdiff_t>(-src.width(),1);
    }
}

ʵ=֐ "src_loc[above]" 攓據﬋ٵĖ蕫˷ҽ♗笒ⶸŠꜸ߮

䴽蠣IL ˣ蓄켓紵﵄঱a>

ȃΒCѠx_gradient 轀ӷ껯. ˣ稓渃ʊꏈκεč쏱ʓͼ,ֻҪ˻CӐϠͬ儑Չ덨睬抽.ςaʇЂ퓿ڵđ闓:

template <typename SrcView, typename DstView>
void x_gradient(const SrcView& src, const DstView& dst) {
    gil_function_requires<ImageViewConcept<SrcView> >();
    gil_function_requires<MutableImageViewConcept<DstView> >();
    gil_function_requires<ColorSpacesCompatibleConcept<
                                typename color_space_type<SrcView>::type, 
                                typename color_space_type<DstView>::type> >();
    
    ... // compute the gradient
}

ϖԚ儐‹㷨ʹ僊䈫傻쏱ʓͼ Ѝ漳ɎꄣॲΊբģॲΊҔʹӃĚćILͼϱʓͼ Ѝ,ҲԊ鈴Ӄ맗Զ蒥傻쏱ʓͼ Ѝ. ςa儈퐐ꯊ튇ᵄ;˼CʹӃ boost::concept_check ȷᣊ䈫俊ʽʴӚ GIL ͼϱʓͼ, ⢇ҵڶ⎊ʇ䵄,˼C儑Չ뿕줒⊇즈ݵĨ=ȧ,Џͬ傻貲ʽ) .

GIL ⢲뇿dzʹӃGIL億ڽ翕Ԭ Ѝ, ģԊ鈴ה캶蒥儑Չ덨倬ѕɫ䬵촺Ʒ,樎놷,ͼϱʓͼꍍ쏱. 嫊ǒꏫʹӃGIL, ˼Cᘐ낺ףһש̵쾻밾仰˵, ˼Cᘐ늇GIL腄ģЍ. GIL儸ńҥԚӃ맊鈴ʖ⡖

ԚC++纐ͱೌ֐ʹӃģॵėᗶ˖DZҫ儴펳ϻϢđҔ-բʇӉӚȱ禔熚儀Ѝ쬲鵼ւ儸ᗷӃ-һ趷ꐍ⎊Ĝ⻂ꗣꯊҪdz,բ֖ǩﶿɄܔں܉Ƕ̗⣴Ζű뷢ϖ, 淵⺍䭎㵄ᾖʒѾ폠⮊ˇ瀯. GIL ʹӃ boost::concept_check 4ᜃ╢֖Ί̢. ɏa儕∽ꯊ퓃4쬑鄣ॲΊ튇籊䓚Ϡ阸ńģЍ, ȧ黃㐍ʇ䭎㵄,ćo᠒뵄䭎㏻Ϣᔚ ꯊil_function_requires֐⺉ꬠբꍷ≺䭎㵄嗥㣵Ľӽ쬒⒗Ӛ躗ٮ բ֖쬲鷢ɺԚ᠒놚,uӐԋʱ儐ԄܓϬ. ʹӃ腄⩵Ĉᵣʇ˻C롸狙ҫʱ줴耴֘儓Ϭ,բҲʇΪʲoGILֻʇԚdebugģʽςִ腄⩵Ĕ풲,Ҳ촖듐ꪠ BOOST_GIL_USE_CONCEPT_CHECK 樒嵄ʱ겲ſɒԠ(Ĭȏʇ阱յĩ.

纐ͺ監猥ꍷǷꐍ঱照〠ˆ靚׮䳵IJʇҪ攏ዘ儑Չ덨啥萐ѭ뷬솋ヿ趍貲儌ݶȺ

template <typename SrcView, typename DstView>
void x_gradient(const SrcView& src, const DstView& dst) {
    for (int y=0; y<src.height(); ++y) {
        typename SrcView::x_iterator src_it = src.row_begin(y);
        typename DstView::x_iterator dst_it = dst.row_begin(y);

        for (int x=1; x<src.width()-1; ++x)
            for (int c=0; c<num_channels<SrcView>::value; ++c)
                dst_it[x][c] = (src_it[x-1][c]- src_it[x+1][c])/2;
    }
}

攃︶ͨ伀鈴һ趏Ԋѭ뷿Ʉܻኇһ趐Ԅ܎ʌ⬇ILԊΒC㩏㶔y趍貲儲ٗ紖p>

template <typename Out>
struct halfdiff_cast_channels {
    template <typename T> Out operator()(const T& in1, const T& in2) const {
        return Out((in1-in2)/2);
    }
};

template <typename SrcView, typename DstView>
void x_gradient(const SrcView& src, const DstView& dst) {
    typedef typename channel_type<DstView>::type dst_channel_t;

    for (int y=0; y<src.height(); ++y) {
        typename SrcView::x_iterator src_it = src.row_begin(y);
        typename DstView::x_iterator dst_it = dst.row_begin(y);

        for (int x=1; x<src.width()-1; ++x)
            static_transform(src_it[x-1], src_it[x+1], dst_it[x], 
                               halfdiff_cast_channels<dst_channel_t>());
    }
}

static_transform ʇһ趇ILͨ值汰儋㷨,Ƥ˻ ˆ儋㷨빓static_generate, static_fillstatic_for_each. ˼CԚSTL֐攓抇 generate, transform, fillfor_each . GIL ͨ個㷨ʹӃ쵝駑萐ѭ뷻˼C⻻ᶔͨ啥萐ϔʽ儑. ҪעҢijϖ褻ıҫƷ(ցəӐ Visual Studio 8) 롕鿪ͨ值汰儑(ҫ՟ע:촊ǔڲ늹Ӄhalfdiff_cast_channels,ʹӃ˫⣑儊Ẳ,᠒놷롏볽Ě⣵đ,բϔȻʇһ֖蟼淨᠒듅믩,ꍉσ淨һѹ. 嫊NJ鈴GILͨ值汰儋㷨俊퍢һ趓ŊƊǺ ʹ動貲ֵԚӯҥɏ攓憰4,渲뱘Ҁ5ӚĚ䦵Ĵΐ⬠=ȧ, ɏa儴ꂫԆ晃һ趒GB儔䀠Ѝꍒ븶BGR億ﱪ Ѝ.

ςa儴ꂫʇ҃Ǻ儷ꐍ঱ӃԚ⻍쵄ͼϱ Ѝɏ:

// 16-λ뒶ȼ抽瓃
void XGradientGray16_Gray32(const unsigned short* src_pixels, ptrdiff_t src_row_bytes, int w, int h,
                                  signed int* dst_pixels, ptrdiff_t dst_row_bytes) {
    gray16c_view_t src=interleaved_view(w,h,(const gray16_pixel_t*)src_pixels,src_row_bytes);
    gray32s_view_t dst=interleaved_view(w,h,(     gray32s_pixel_t*)dst_pixels,dst_row_bytes);
    x_gradient(src,dst);
}

// 8λ儒GB影6λ儂GR
void XGradientRGB8_BGR16(const unsigned char* src_pixels, ptrdiff_t src_row_bytes, int w, int h,
                                 signed short* dst_pixels, ptrdiff_t dst_row_bytes) {
    rgb8c_view_t  src = interleaved_view(w,h,(const rgb8_pixel_t*)src_pixels,src_row_bytes);
    rgb16s_view_t dst = interleaved_view(w,h,(    rgb16s_pixel_t*)dst_pixels,dst_row_bytes);
    x_gradient(src,dst);
}

// ԴꍄﱪʇҲ漿ɒԊdž탦 Ѝ - ̝戴ꂫҲʇ⻱ظı䵄
void XGradientPlanarRGB8_RGB32(
           const unsigned short* src_r, const unsigned short* src_g, const unsigned short* src_b, 
           ptrdiff_t src_row_bytes, int w, int h,
           signed int* dst_pixels, ptrdiff_t dst_row_bytes) {
    rgb16c_planar_view_t src=planar_rgb_view (w,h, src_r,src_g,src_b,         src_row_bytes);
    rgb32s_view_t        dst=interleaved_view(w,h,(rgb32s_pixel_t*)dst_pixels,dst_row_bytes);
    x_gradient(src,dst);
}

սȧʵ=˹ᭃ組,Դꍄﱪ傻쏱 ЍԊǼ臨靚ƽa靚Ȏꎵč貲ɮ戨왶脿᪀ЍʇԱ딴 Ѝ賒嵄),Ȏꎼ賊儑Չ뿕줮

GIL 2.1 비ڔڵĖ糖爛ֽڶԆ뵄ͼϱ Ѝ, =ȧ 6-λ RGB222ͼϱ법߱-λ儻Ҷȍ쏱. GILĚԚ֧㖕▖傻쏱 Ѝ, Ԕډ輆ָďꍊ΄쾖鿴բ罃渼Ϫϸ儐ŏ⮼h3> ͼϱʓͼ᤻뼯a> 솋㴹ֱ̝戟ā풻趷ʇתͼϱ90, 솋㋮ƽ̝戩Ȼ곔ٰѽṻת똀䮠ςaʇʹӃGIL嵄亂됎ʽ:

rotated90ccw_view Ҕͼϱʓͼ׷Ϊ⎊⇒絻ؒ븶ԚĦʱի罏≏ת90戟č쏱ʓͼ. բʇһ趇ILͼϱʓͼ᤻뵄ʵ=. GILӐ䳁﵄բѹ儱任ꯊⰼ(빓ڗ豪֡ȎҢ罏ⵄת,ʓͼ᤻무閱법ߋ罏ⵄ仲ꬾؐΗӊӍ콘ȡ,ѕɫ᤻묗ӊӍ첉ѹ刵Ȯ rotated90cw_viewʇբ᤻뺯ʽ֮һ, 僵튓ͼ儋弴ꆷʇԭʓͼ儴閱弴ꆷ. ɏa솋㴹ֱ̝戟Ĵꂫܓɓڄڴ卷Ίģʽ載ʌ⬵얂˙或; 嫕ⲻʇꯊode>rotated90cw_view 儊¼/code>

빓븶=ד: 왈玒CҪ솋㎎쑕ɫͨ佞ռ䍼ϱ儌ݶȬԕ6׶:

nth_channel_view ʇһ越Ӎ엪뻺,˼ђ븶Nάѕɫͨ佞ռ䵄ʓͼת뻎굥һѕɫͨ倨뒶ȩ儊Ӎ쮀툧攓ڒGBʓͼ, 絻صĽṻǒ븶̘樲儊Ӎ쬆䋮ƽ弴ꆷǰĶ花견롌蹽}趍貲. ȧ黓擃ԚƽaRGBʓͼɏ,絻ؾ͊ǒ븶ˮƽ弴ꆷΪCʽָի儻ҶȊӍ쮠ͼϱʓͼ儱任ꯊҔЇ抉. =ȧ,ΪK솋ㅼʽλϱ˘嚶ͨ倵ČݶȖ嬿ɒԕ6:

GIL Ӑʱ겻ἲ믇抉ʓͼ儊鈴. =ȧ}趇抉儗ӊӍ쨏ዘԚXꍙ罏≏)Ա폖Ϊһ趵咻儗ӊӍ쬆䏱˘̸Ծ⽳䊇}趗ӊӍ쌸Ծ⽳䵄㋻h3> һάϱ˘弴ꆷ ȃΒCԙ䎻صʽ x_gradient . Ꜷൄʱ겎҃ǐ蒪攍쏱ʓͼ儃︶ϱ˘Џͬ儋㷨♗芐IL̡驁˕6儳錚뺖Ʈ ΒC儋㷨ʹӃKһ֖照㹦儷Iʻꖆ,˼⻷Iʵڒ뺍׮곒끐. ȧ黎҃NJ鈴ͬһ儐Ί햘ˣ稿ͺAˬ⢇ҕ6Ҳ꜓̑琉ҥ.ΒCҪʵϖբѹ儒븶঱ٗ݃︶ϱ˘,嫊Dz밼ꬍ쏱儵ڒ끐ꍗһP.ʹӃGILΒCԕ6׶:

void x_gradient_unguarded(const gray8c_view_t& src, const gray8s_view_t& dst) {
    for (int y=0; y<src.height(); ++y) {
        gray8c_view_t::x_iterator src_it = src.row_begin(y);
        gray8s_view_t::x_iterator dst_it = dst.row_begin(y);

        for (int x=0; x<src.width(); ++x)
            dst_it[x] = (src_it[x-1] - src_it[x+1]) / 2;
    }
}

void x_gradient(const gray8c_view_t& src, const gray8s_view_t& dst) {
    assert(src.width()>=2);
    x_gradient_unguarded(subimage_view(src, 1, 0, src.width()-2, src.height()),
                         subimage_view(dst, 1, 0, src.width()-2, src.height()));
}

subimage_view ʇGILͼϱʓͼ᤻끭͢儒븶=ד. ˼儊䈫ʇһ趍쏱ʓͼꍒ븶·蓲(Ԛբ/촊Ƕ蒥 x_min,y_min,width,height) ,ʤ㶒븶༺앢趾ؐ·蓲儊Ӎ쮉σ淨ʵϖϠ攓ڲٗݔ튼儊Ӎ쬃듐÷ϔ儐Ԅ܍˻﮼p> 攓ں x_gradient_unguarded ♗݃︶ϱ˘, ΒCԊ鈴輽䴕儐Ί

void x_gradient_unguarded(const gray8c_view_t& src, const gray8s_view_t& dst) {
    gray8c_view_t::iterator src_it = src.begin();
    for (gray8s_view_t::iterator dst_it = dst.begin(); dst_it!=dst.end(); ++dst_it, ++src_it)
        *dst_it = (src_it.x()[-1] - src_it.x()[1]) / 2;
}

GIL ͼϱʓͼ̡驁˺ begin() ꍠend() ,˼C絻ؒ뎬粲ዘ弴ꆷ,攍쏱儃︶ϱ˘촺, 䓗㵽Ӓ,䓉ϵ폂. 弴ꆷˇᵱ儻ؗꭔڃ儽Ꮂ˼C롌蹽ΞӃ儗ֽڮ ˹Ҕ,˼C儐ԄܓŻﲻʇ׮쑬 ҲΪ˻CҪ躗ٵᇰλփϠꍐЎⵄ閼寵쓲ٗ琨Ҫ벣殍ⵄ쬲騎҃ǵ퐐βK°?),淵⸶쬲錨ʹӃǶ̗ѭ뷵ĊẲʇ⻐蒪儮 բ弴ꆷ̡驁ˇၿ춵ķ x() ,Ӄ4僵펒CǰaʹӃ儋弴ꆷ. ˮƽ弴ꆷ⻖굀ꍐЎⵄ閼寵Ԛᾀ햐,ˮƽ弴ꆷǃʽָի. ԚΒC儀헓֐,ᘐ늹Ӄˮƽ弴ꆷսȷ儷IʁZ ҲΪ˼C܎듚ͼϱʓͼ֮͢.

STL 攓揀稼/a>

GIL ̡驁˺ܶຍ STL攓淨ˣ種 =ȧ, std::transform ʇһ趓TLˣ糯˼ʹӃһ趷ꐍꯊ׷һ趇輤儋銬Ԫ˘,⢇Ұѽṻ煔ڶԓ淨Ŀ᪇輤֐. ԚΒC儊啥֐, ΒCҪє䊓ͼy趏ዘˮƽϠZֵ⮵Ē밫賸趔Ӧ億ﱪϱ˘. ȧ黊鈴һ趷o4㩏㕢趲ٗ笎҃ǿɒԊ鈴GIL儺 transform_pixel_positions բѹ׶:

GIL ̡驁˺͓TL儋㷨for_each_pixeltransform_pixels攓淨ˣ稼code>std::for_each ꍠstd::transform . m͢빌ṩKꯊcode>for_each_pixel_position ꍠtransform_pixel_positions, ˼C⻊NJ鈴ϱ˘ҽӃ,淵NJ鈴ϱ˘樎놷. բѹͨ齶莻Ʒ,Ԋ鈴ϱ˘ϠZ監美곉轀Ӈﴳ儹愜. GILˣ稒⿉ҔʹӃ}⣇抉儑4̡蟐炊(渲늇ʹӃһά儵촺Ʒ)

ѕɫ᤻뼯a>

Ӑ儊ẲΒC⻊ǒ꼆ˣͼϱѕɫ儌ݶȬ淵ǒ꼆ˣՕ÷戟ČݶȮ뻾仰˵,ΒCҪ쏱儑Չ떵תᤵ或嬈뺳솋ㆤ̝戮ΒC솋㳲λ衵㊽RGBͼϱՕ÷戟ČݶȬ亂눧ς:

void x_gradient_rgb_luminosity(const rgb32fc_view_t& src, const gray8s_view_t& dst) {
    x_gradient(color_converted_view<gray8_pixel_t>(src), dst);
}

color_converted_view ʇһ趇ILʓͼ᤻뺯ʽ,ʤȫʇȎҢ傻쏱ʔͼ Ѝ,絻ؒ븶̘樑Չ뿕줺͍貲 Ѝ傻쏱ʓͼ(ѕɫ亍ѕɫͨ倍蹽ģॲΊҥ). Ԛɏa儊啥֐,ͨ齒븶32λ衵㒇Bϱ˘ Ѝ儊Ӎ칹ԬKһ躉λ뒶ȕ됍ֵʓͼ. ꍆ䋻傻쏱᤻뺯ʽһѹ, color_converted_view ʇһ趿싙dzア享ʽ. ˼uӐЊア䬒⃻Ӑִѕɫ᤻뮠˼ֻʇ絻؁ˊӍ쬔ڃﴎ烎ʏዘ儊ẲЊ勵솋㮼p> Ԛ纐͋㷨֐,ΒCҲֻʇҪՉ뱤뻎껒或嬶豣㖆䍨倀Ѝһւ. ΒCЈ珂♗笠鷫캍Դʓͼͨ倀Ѝһւ儻Ҷȏዘ Ѝ,Ȼ곰Չ뗪뻎궔Ӧ粲ዘ Ѝ:

template <typename SrcView, typename DstView>
void x_luminosity_gradient(const SrcView& src, const DstView& dst) {
    typedef pixel<typename channel_type<SrcView>::type, gray_layout_t> gray_pixel_t;
    x_gradient(color_converted_view<gray_pixel_t>(src), dst);
}

ȧ黃ﱪѕɫ亍ͨ倀Ѝꍔ䊓ͼ儒떂, ѕɫ᤻뾍uӐᘒꮠGILĜ黼첢錄Ⓕ壬䓶蓀ȫᜃ⑕ɫ᤻뮠ҲNj弣ode>color_converted_view 廘ԭ4儊Ӎ젼h3> ͼϱ ɏa儴ꂫ䦔ڒ븶ĜΊ̢-ꯊ_gradient 放貰櫳ϱ˘ҽӃ}䎨ҫ՟ע:y趄ﱪϱ˘ֵ솋㐨ҪҽӃԴϱ˘ֵ}䎬ҲΪҪ솋㶾՟֮⮩,Ҳ漸蒪᤻뮓ЊẲⒻ趁يỺ㥇謶Կ儔䍼ϱ솋ㆤ̝戒␭轀ӓ笠ҲΪբѹѕɫ᤻떻Ҫ봎. Ƥ燷ꐍˣ稈珂:

void x_luminosity_gradient(const rgb32fc_view_t& src, const gray8s_view_t& dst) {
    gray8_image_t ccv_image(src.dimensions());
    copy_pixels(color_converted_view<gray8_pixel_t>(src), view(ccv_image));

    x_gradient(const_view(ccv_image), dst);
}

ʗψΒC鷫쒻趺͔䊓ͼЏͬά戟ĸλ뒶ȍ쏱Yʱ뺳凸, Ȼ곎҃ǰՉ뱤뻺㵄ʓͼア䵽Yʱ뺳凸,׮곎҃ǰ㷨 x_gradient ӦӃԚբ趁يỺ㥇翕Ԭ監북ʓͼɏ. սȧʵ=˹ʾ, GIL ̡驁ˈ뾖ꯊcode>view ꍠconst_view 쏱תᤎꏱ˘亍⻿ɱ䵄ʓͼ.

䴽艏aˣ滋ķꐍ঱Ҫһ壯ĐἼlj:

template <typename SrcView, typename DstView>
void x_luminosity_gradient(const SrcView& src, const DstView& dst) {
    typedef typename channel_type<DstView>::type d_channel_t;
    typedef typename channel_convert_to_unsigned<d_channel_t>::type channel_t;
    typedef pixel<channel_t, gray_layout_t>  gray_pixel_t;
    typedef image<gray_pixel_t, false>       gray_image_t;

    gray_image_t ccv_image(src.dimensions());
    copy_pixels(color_converted_view<gray_pixel_t>(src), view(ccv_image));
    x_gradient(const_view(ccv_image), dst);
}

ʗψΒCʹӃԪꯊcode>channel_type 僵턿᪊Ӎ쵄ͨ倀Ѝ. ˹νԪꯊʇ♗݀Ѝ儺. ԚGIL֐,Ԫꯊʇբѹ儽ṹ̥:Ҕ Ѝ׷ΪģॲΊ蹽Ƕ̗儴ypedefʤ㶽ṻ Ѝ,⢇҃샻Ϊ type. Ԛբ越啥֐, channel_type ʇһ趒딪Ԫꯊ䈫һ越Ӎ쀠Ѝ,僵풻趺͊Ӎ쀠Ѝ閣굄ѕɫͨ倀Ѝ.

GIL 鷫쵄Ϡ閥Ѝༀ躠ϱ˘ Ѝ, ϱ˘弴ꆷ,樎놷,ͼϱꍊӍ쀠Ѝ剷 ˼C漊Ǹńcode>PixelBasedConcept 億㐍, բҢζׅ˼C堇ṩKһשԪꯊ퀴⩑˘儊䐔,=ȧ channel_type, color_space_type, channel_mapping_type, ꍠnum_channels.

僵턿᪊Ӎ쵄ѕɫͨ倀ЍҔ곬ΒCʹӃm͢һ趔꺯ʽɾ㽆䀠Ѝ儷뺅λ(ȧ黴攚綹Ŏ뵄방,Ȼ곾ܹ̈́뵃徹Ҷȏዘ Ѝ.䓏ዘ ЍɒԵo퍼ϱ Ѝ. ʹӃϱ˘ Ѝꍖ芾ͼϱʇ줸亍빊dž탦儲춻ֵ׷ΪģॲΊ錟ͼϱ Ѝ. GIL֐儵契倨뒶ȼ橍쏱ᘶ芇줸䵄. GILԊ鈴棲ַ튽鷫썼ϱ Ѝ, 㽁˖ὓ鷫쬠ΒC빿ɒԊ鈴 Ѝ餳甪ꯊ䵈웵Ĵꂫȧς:

template <typename SrcView, typename DstView>
void x_luminosity_gradient(const SrcView& src, const DstView& dst) {
    typedef typename channel_type<DstView>::type d_channel_t;
    typedef typename channel_convert_to_unsigned<d_channel_t>::type channel_t;
    typedef typename image_type<channel_t, gray_layout_t>::type gray_image_t;
    typedef typename gray_image_t::value_type gray_pixel_t;

    gray_image_t ccv_image(src.dimensions());
    copy_and_convert_pixels(src, view(ccv_image));
    x_gradient(const_view(ccv_image), dst);
}

GIL ̡驁˒뗩Ԫꯊ퀴⺉ꇉL儀Ѝ- image_type ʇբѹ儔꺯ʽ֮һ,˼ͨ齸趨傻貲 Ѝ,ѕɫ⼾֬ƽa儻銇줸䵄(Ĭȏ儊Ǽ臨儩4鷫썼ϱ Ѝ. 빓І䋻 ˆ儔꺯ʽ,Ӄ4鷫쏱˘ҽӃ,弴ꆷ,樎놷ꍍ쏱ʓͼ. GIL 빌ṩKȧς儔꺯ʽ derived_pixel_reference_type, derived_iterator_type, derived_view_typederived_image_type ,բԪꯊ퍨齸ı丸樵Ĕ䍼ϱ Ѝ儒븶법߶ึʴ,⢇ұ㳖Ƥ˻儊䐔⻱䀴鷫쐂傻쏱 Ѝ.

ͨ齍쏱 ЍǶ̗儀Ѝ樒封code>value_type Եo폱˘儀Ѝ. GIL ͼϱ,ͼϱʓͼꍶ莻Ʒ漓Єڇ淨 Ѝ樒封code>value_type ꍠreference ,ָϲϱ˘ꍏዘҽӃ儀Ѝ.ȧ黃㓐һ趏ዘ弴ꆷ,ģԊ鈴 iterator_traits 4뱵O␩ Ѝ樒寵m͢빒ꗢҢ彋㷨ꯊcode>copy_and_convert_pixels ʇꯊode>copy_pixels ʵϖѕɫת뻵Ē븶Ⱖᾮ

Ģͼϱʓͼ

彏֔ڎꖹ,ΒCĜ黴怭ϱ˘ĚȝԚĚ䦖č쏱 ЍK. GIL Ԋģ䴽舍ꎍ쏱儊Ӎ쬰쀨ꏳɺ. ΪK˵÷բһ壬ΒC䴽蒻趠Mandelbrot 쯵ĊӍ쮠ʗψ,ΒCҪ樒帶為, Ӄ4솋㔚ͼϱԚ踶莻փx,y䦵ĠMandelbrot 쯺Ϩҫ՟ע,⎼뼡>http://en.wikipedia.org/wiki/Mandelbrot_set)儊햵
// models PixelDereferenceAdaptorConcept
struct mandelbrot_fn {
    typedef point2<ptrdiff_t>   point_t;

    typedef mandelbrot_fn       const_t;
    typedef gray8_pixel_t       value_type;
    typedef value_type          reference;
    typedef value_type          const_reference;
    typedef point_t             argument_type;
    typedef reference           result_type;
    BOOST_STATIC_CONSTANT(bool, is_mutable=false);

    mandelbrot_fn() {}
    mandelbrot_fn(const point_t& sz) : _img_size(sz) {}

    result_type operator()(const point_t& p) const {
        // 馸ữ׸᪎꠨-2..1, -1.5..1.5)
        double t=get_num_iter(point2<double>(p.x/(double)_img_size.x*3-2, p.y/(double)_img_size.y*3-1.5f));
        return value_type((bits8)(pow(t,0.2)*255));   // owerԋˣҔᣲ鿴
    }
private:
    point_t _img_size;

    double get_num_iter(const point2<double>& p) const {
        point2<double> Z(0,0);
        for (int i=0; i<100; ++i) {     // 100 䎵촺
            Z = point2<double>(Z.x*Z.x - Z.y*Z.y + p.x, 2*Z.x*Z.y + p.y);
            if (Z.x*Z.x + Z.y*Z.y > 4)
                return i/(double)100;
        }
        return 0;
    }
};

ϖԚΒCԊ鈴բ趷oꍇIL儼code>virtual_2d_locator 4鷫쒻趠200x200 ϱ˘傻andelbrot쯊Ӎ캼div class="fragment">

typedef mandelbrot_fn::point_t point_t;
typedef virtual_2d_locator<mandelbrot_fn,false> locator_t;
typedef image_view<locator_t> my_virt_view_t;

point_t dims(200,200);

// ʹӃ樎놷鷫썡ndelbrotʓͼ, 䓗㉏퇿ꊼ,⽳䊇(1,1)
my_virt_view_t mandel(dims, locator_t(point_t(0,0), point_t(1,1), mandelbrot_fn(dims)));

ΒC԰ѕ⸶ꏳɺ鷫쵄ͼϱͼ屳ɕ敿傻쏱һѹʹӃ. =ȧ,Ե瓃ΒC儋㷨 x_gradient ,솋㍡ndelbrot 쯐헪90ᣒԺ㵄̝戩⢇Ұє튼ͼϱꍽṻͼϱ䦴⏂4:

gray8s_image_t img(dims);
x_gradient(rotated90cw_view(mandel), view(img));

// 䦴⍡ndelbrot쯺͐헪90ᣒԺ㵄̝戨jpeg ⻄ܴ洢Ӑ綹ŀЍ,ᘐ뗪뻎뎞綹ŀЍ儩
jpeg_write_view("mandel.jpg",mandel);
jpeg_write_view("mandel_grad.jpg",color_converted_view<gray8_pixel_t>(const_view(img)));

ςaʇբ}趎ļ䦴⽡黵đ闓:

mandel.jpg

ԋʱָʼn傻쏱ꍍ쏱ʓͼ

彏֔ڎꖹΒCĜ黊鈴纐ͺ솋㓉ģॲΊԬ傻쏱ʓͼ儌ݶȁˮ 嫊ǓĊẲͼϱʓͼ儊䐔,=ȧѕɫ䬍貲ɮ戩Ԛ᠒놚Ξ滋oGIL儀久dynamic_image ,Ҳ퐱䌥, ʹ僇IL儹錟Թ䗷Ԛԋƚ. GIL̡驁˔ːІڊ啥믵č쏱 Ѝ any_image_view, ꍔːІڊ啥믵č쏱ʓͼ Ѝany_pixel_iterator. 䴽膤˻ᤌ嵄뺖ƒⶼӐ,=ȧ any_pixel, any_pixel_iterator刵Ȯ 㶠ʽ儇ILˣ稚͋銬儊Ӎ엪뻺漊ʓ據ԋʱ儀Ѝ. m͢澔ꋣ糯=ȧcopy_pixels , Ƥ֐儒븶법߁⎊ʇᤌ倠Ѝ.

ΒC;Ӄˣ稼code>x_luminosity_gradient 4˵÷ᤌ卼ϱʓͼ Ѝ儊鈴.ΪK첻﬎҃ǖ늇왶麻ʓͼΪᤌ倠Ѝ. (׷ΪʹӃ核湯̥ Ѝ儊,⎿쇉L≓oึᤌ坋ʽ֘Ԙ儋㷨ꯊ

ʗψ,ΒC鷫쒻趷o,ҔĿ᪊Ӎ쀠ЍΪģॲΊͬʱ為儓擃♗緻ҔԴʓͼ ЍΪģॲΊp>

#include <boost/gil/extension/dynamic_image/dynamic_image_all.hpp>

template <typename DstView>
struct x_gradient_obj {
    typedef void result_type;        // բ/Ҫtypedef
    
    const DstView& _dst;
    x_gradient_obj(const DstView& dst) : _dst(dst) {}

    template <typename SrcView> 
    void operator()(const SrcView& src) const { x_luminosity_gradient(src, _dst); }
};

嚶ʇ̡騶x_luminosity_gradient 儒븶֘Ԙ঱쒔ᤌ卼ϱ Ѝ׷Ϊ⎊Ȼ곰ѕ⸶為׷Ϊ⎊垢臉L儺 apply_operation巔u

template <typename SrcViews, typename DstView>
void x_luminosity_gradient(const any_image_view<SrcViews>& src, const DstView& dst) {
    apply_operation(src, x_gradient_obj<DstView>(dst));
}

any_image_view<SrcViews>ʇһ趍쏱ʓͼᤌ倠Ѝ. ˼億㰥⎊튇SrcViews, բʇᤌ倠Ѝ˹Ӑ܍쏱ʓͼ Ѝ儒븶o src Ě⿰캬Kһ趵ᇰʵ=므Ѝ儋璽,ͬʱ빰캬ͼϱʵ̥億ڴ浘ַ. ꯊcode>apply_operation ͨ齒븶switch ӯ遠˷ҽ,Ԛy趣aseӯڲﬠㄚ䦗ꐍΪ攓淨ʓͼ Ѝʵ=攏㬈뺳ի攕⸶攏㵷Ӄ為.ի庋䌥 Ѝ巔×귢롲ꉺswitchӯĐԄܿꏺ.嫊Ƕԓڱ䌥y趍쏱ʓͼ粲ዘ♗狣糯 ʵ슉ϲ뻡一䐔Ĝ˥͋.

ςaʇΒC鷫챤̥ Ѝ儊啥,Ȼ공瓃Ϡ鬩㷨儴ꂫeʶ:

#include <boost/mpl/vector.hpp>
#include <boost/gil/extension/io/jpeg_dynamic_io.hpp>

typedef mpl::vector<gray8_image_t, gray16_image_t, rgb8_image_t, rgb16_image_t> my_img_types;
any_image<my_img_types> runtime_image;
jpeg_read_image("input.jpg", runtime_image);

gray8s_image_t gradient(runtime_image.dimensions());
x_luminosity_gradient(const_view(runtime_image), view(gradient));
jpeg_write_view("x_gradient.jpg", color_converted_view<gray8_pixel_t>(const_view(gradient)));

Ԛբ趀헓屖 ΒC䴽聾һ趿Ʉ܊Ǹλ,16λ儒GB Ѝ벻Ҷȼ怠Ѝ傻쏱. Ȼ곎҃ǵ瓃GIL儉/O )չ, 䓎ļԘƤѕɫ亍ͨ倉. ȧ黴Ņ̵ĎļƥŤΒC踶資 Ѝ, ᅗ㶒븶Ҭ㣮 퓗Ŏ҃ǹ錟һ趓뺅傻쏱 Ѝ4䦴⌝戩 ςһ⽵瓃ꯊode>x_gradient 솋㌝戮 ׮곎҃ǰѽṻ䦴⵽m͢һ趎ļΒC쏱䦴⎪8λΞ綹ŀЍ, ҲΪJPEG I/O ⻖糖Ӑ綹ŵģhar Ѝ.

עҢբהӉꯊ罷輣ode>jpeg_read_image, dimensions, viewconst_view ʇȧꎹ䗷ԚģॲΊᤌ倠Ѝ⎊퉏儮 攓ڄ㰥믵č쏱ꯊew(img) 僵풻趄㰥믵Ġview, 渱䌥 Ѝ傻쏱Բ僵풻趲䌥 Ѝ傻쏱. =ȧview(runtime_image) 儷廘 Ѝʇ any_image_view<Views> ,Ƥ֐儠Views oˏ๘儴֖ͼϱ Ѝ. const_view(runtime_image) 僵֖북儠any_image_view Ѝ.

ʹӃᤌ倠Ѝ儒븶溠ʵ=믱䌥 Ѝ⎊ˣ稿ͻኵ=믋銬ܵĊӍ쀠Ѝ. 攓ڲԪˣ稶葔, բҢζׅҪʵ=믋銬܀Ѝ儲Ԫשꏡ բ롒톰᠒늱줺͖䐐㌐ⴳ儅╍.

ۼ/a>

բ趽̳̕汞KʹӃGILˣ稽萐纐ͻ︟ͼϱ䦀跖֌䕽. ΒCʹӃһ趺ܼⵥ儋㷨,ʹ֮Ĝ黹䗷Ԛ跖և鿶ς,բༀ費ͬ儴洢λʽ,ѕɫ䬍貲䎐⒔찲덬儆탦/줸佡鹮 ΒCչʾKˣ稊ʓOڍꈫ㩏㵄ͼϱ Ѝ, ɵց빰쀨ԋʱ傻쏱 Ѝ. Ϡ陣Ċӆ彌㌻久ϖKԚ贔ӳᾰςɺ㉵Ĵꂫ, ƤĜҲԺ͕붔ij֖̘樍쏱 Ѝ儊֐䃴ꂫϠ懃.

嫊Ǭɵցֻʇբѹһ趼ⵥ儋㷨,덪ȫ紵ﺍͪȫӅ믻麜Զ. =ȧ, ʹӃ儋㷨빖넜♗ݍ얊傻쏱 Ѝ, ҲǏዘ傻貲 Ѝᘐ늇Ϡͬ儮 ʵ슉ϴ攚բѹ傻쏱,=ȧѹ˵儵65 RGB 豊Ƥѕɫͨ倀Ѝʇ⻒떂儮 GIL̡驁˲ٗݒ얊ͼϱ Ѝ儸ńˣ糯ΒCѕ⸶)չˣ蓄_gradient 儹䗷t踶U߮ 嚶솋̝或卡곬 ΒCֻʇ첵嵄엪뻎넿᪍貲儀Ѝ, 嫊Ǖ⿉Ĝ⻊ǎ҃džڍ뵄Ϊ. =ȧԴͼϱ傻貲ʇ[0..1] 綎焚儸ᵣʽ, 渄ﱪ Ѝʇunsigned char , բᔬ㉄ﱪ뗜ʇ0벱. 淵弊ɏΒCܐ蒪봎˵煬ʹ僽ṻԚĿ᪀Ѝֵ儷控Ě. =ȧ,ꯊode>channel_convert ᔚ⻍써倀Ѝ֮줽萐ϟ˵煬ʹ僔䍨倖嵄綎瘓뻎ꄿ᪍貲ֵ儷控.

攓ڌḟĜҲ빓ܶ๤׷Ҫ׶. ͨ值汰儲ٗ笀툧૲׷, Գ錚㉎ꍨ值汰儔헓ˣ糯 淵䐔ĜϻꄿɒԸ秋嵄ͨ倀Ѝᔱ. m͢Ԋ鵃ij♗畫攓ڌض資䦀톷, =ȧͬʱ♗ݒ땻粲ዘֵ, 법߽萐ʽ䈡. ի攷ꐍˣ滋ĐԄ܌ػﰦᾶ쿉Ҕʵϖ. ׮곬ˤȻ᠒놷롔퀴Խꃬ嫊LjԈ뿉Ĝ攓ڷꐍ亂벻ĜӅ믵ć鿶, =ȧĚj믄㐩ꯊ՟ђ됩ᤁﷅԚ섴楚屖 ȧ黐Ԅ܊ǒ븶Ί̢, ʹӃ⻍쵄᠒놷⢊Ԅ㵄亂뒲ʇһ쾖嵃儊‡鮼h2> 轂켯a>

GILʵ̥ Ѝ儃샻Լ樼/a>

GILʵ̥(⻊Ƿ껯儩 Ѝ儃샻Լ樹늽ʇ:

ColorSpace + BitDepth + [f | s]+ [c] + [_planar] + [_step] + ClassType + _t

Ƥ֐ ColorSpace ָʾKѕɫש㉵Ĵΐ⮠=ȧrgb, bgr, cmyk, rgba. BitDepth ָʾKѕɫͨ倵Ď늽,=ȧ 8,16,32. Ĭȏ傻貲 ЍʇΞ綹ŕ됍;ʹӃsᭃ奔Ӑ綹ŕ됍,fᭃ奔衵㊽,˼לʇӐ綹ŵĮ cᭃ疻Ĝ攏ዘ북♗箠_planar ᭃ奔ƽa鴟(բꍼ臨鋒攩. _step ָʾ̘樵č쏱ʓͼ, 樎놷ꍵ촺ƷҔnon-trivial罊:ʽ=ȧ, ϲ곱遠법߃D賢븶ϱ˘ᩀꩮ ClassType ᭃ砼code>_image (ͼϱ), _view (ͼϱʓͼ), _loc (ϱ˘樎놷) _ptr (ϱ˘弴ꆷ), _ref (ϱ˘ҽӃ), _pixel(ϱ˘ֵ).

bgr8_image_t             a;    // 8λ줸䵄BGRͼϱ
cmyk16_pixel_t;          b;    // 16-λ CMYK ϱ˘ Ѝ;;
cmyk16c_planar_ref_t     c(b); // ָϲ16-λƽa那YKϱ˘x儳ҽӃ.
rgb32f_planar_step_ptr_t d;    // ָϲ32-λƽaRGBϱ˘儳tep 弴ꆷ.


Generated on Thu Nov 8 21:53:19 2007 for Generic Image Library by  doxygen 1.4.4