// blend1.cpp : DLL アプリケーションのエントリ ポイントを定義します。 // #include "stdafx.h" #include #include #ifdef _MANAGED #pragma managed(push, off) #endif extern "C" { typedef unsigned char n_byte; int __stdcall get_blend_func_count(); char* __stdcall get_blend_func_key(int no); char* __stdcall get_blend_func_name(int no); void __stdcall blend(unsigned char* dst,const unsigned char* col,const unsigned char* alpha,int col_step ,int alpha_step,int num_channel,int num_pixel,int no); //追加する合成方法の数を返す。 int __stdcall get_blend_func_count() { return 1; } //psdファイルに保存するときのkeyを返す。 /* 'norm' = normal 'dark' = darken 'lite' = lighten 'hue ' = hue 'sat ' = saturation 'colr' = color 'lum ' = luminosity 'mul ' = multiply 'scrn' = screen 'diss' = dissolve 'over' = overlay 'hLit' = hard light 'sLit' = soft light 'diff' = difference 'smud' = exlusion 'div ' = color dodge 'idiv' = color burn */ char* __stdcall get_blend_func_key(int no) { if (no == 0) { return "smud"; } return 0; } //合成方法の名前を返す。 char* __stdcall get_blend_func_name(int no) { if (no == 0) { return "除外"; } return ""; } //合成を行う関数。 //num_channel チャンネル数。グレーモードの場合は1、カラーモードの場合は3 void __stdcall blend(unsigned char* dst,const unsigned char* col,const unsigned char* alpha,int col_step,int alpha_step ,int num_channel,int num_pixel,int no) { if (no == 0) {//除外 // 計算サイト http://www.tagen.tohoku.ac.jp/labo/ishijima/Photoshop-01.html // Overwrap = Bottom+Top-2*Bottom*Top/255 if (num_channel == 1) { // 除外 グレスケ const unsigned char* col_end = col + num_pixel * col_step; while (col < col_end) { double d = 0; d = *dst + *col - 2 * *dst * *col/255 ; *dst = (d * *alpha/255.00) + (*dst * (1.00-*alpha/255.00))+0.5; alpha += alpha_step; col += col_step; dst += col_step; } } else if (num_channel == 3) { // 除外 カラー const unsigned char* col_end = col + num_pixel * col_step; while (col < col_end) { double d = 0; d = *dst + *col - 2 * *dst * *col/255 ; double d1 = 0; d1 = *(dst+1) + *(col+1) - 2 * *(dst+1) * *(col+1)/255 ; double d2 = 0; d2 = *(dst+2) + *(col+2) - 2 * *(dst+2) * *(col+2)/255 ; // レイヤーの色×不透明度 + 下のレイヤーの色×(100%-不透明度) *dst = (d * *alpha/255.00) + (*dst * (1.00-*alpha/255.00))+0.5; *(dst + 1) = d1 * *alpha/255.00 + *(dst+1) * (1.00-*alpha/255.00)+0.5; *(dst + 2) = d2 * *alpha/255.00 + *(dst+2) * (1.00-*alpha/255.00)+0.5; alpha += alpha_step; col += col_step; dst += col_step; } } } } //下のレイヤーと結合で使用される void __stdcall merge(n_byte* dst,const n_byte* col,const n_byte* base_col,const n_byte* alpha,const n_byte* base_alpha ,int col_step,int alpha_step,int base_alpha_step,int num_channel,int num_pixel,int no) { if (no == 0) {//除外 if (num_channel == 1) { const unsigned char* col_end = col + num_pixel * col_step; while (col < col_end) { unsigned int a0 = *base_alpha; unsigned int a1 = *alpha; if (a1 != 0) { double d = 0; d = *dst + *col - 2 * *dst * *col/255 ; // 不透明度を入れた計算 // Ca = 1-(1-Fa)*(1-Ba) //=( Fa *Ba * func(Bc,Fc) + Fa *(1-Ba) * Fc + (1-Fa)*Ba * Bc ) / Ca //http://www.greenwood.co.jp/~k-aki/article/pixel_composite.html double ca = 1 - (1- a1/255.0) * (1-a0/255.0) ; *dst = (a1/255.0 *(a0/255.0) * d + (a1/255.0) *(1-a0/255.0) * *col + (1-a1/255.0)*(a0/255.0) * *base_col ) / ca +0.5; *(dst + 1) = n_byte(((a0 + a1) * 255 - a0 * a1) / 255); } else { *dst = *base_col; *(dst + 1) = *base_alpha; } dst += 2; col += col_step; base_col += col_step; alpha += alpha_step; base_alpha += alpha_step; } } else if (num_channel == 3) { const unsigned char* col_end = col + num_pixel * col_step; while (col < col_end) { unsigned int a0 = *base_alpha; unsigned int a1 = *alpha; if (a1 != 0) { double d = 0; d = *dst + *col - 2 * *dst * *col/255 ; double d1 = 0; d1 = *(dst+1) + *(col+1) - 2 * *(dst+1) * *(col+1)/255 ; double d2 = 0; d2 = *(dst+2) + *(col+2) - 2 * *(dst+2) * *(col+2)/255 ; // 不透明度を入れた計算 // Ca = 1-(1-Fa)*(1-Ba) //=( Fa *Ba * func(Bc,Fc) + Fa *(1-Ba) * Fc + (1-Fa)*Ba * Bc ) / Ca //http://www.greenwood.co.jp/~k-aki/article/pixel_composite.html double ca = 1 - (1- a1/255.0) * (1-a0/255.0) ; *dst = (a1/255.0 *(a0/255.0) * d + (a1/255.0) *(1-a0/255.0) * *col + (1-a1/255.0)*(a0/255.0) * *base_col ) / ca +0.5; *(dst + 1) = (a1/255.0 *(a0/255.0) * d1 + (a1/255.0) *(1-a0/255.0) * *(col+1) + (1-a1/255.0)*(a0/255.0) * *(base_col+1) ) / ca +0.5; *(dst + 2) = (a1/255.0 *(a0/255.0) * d2 + (a1/255.0) *(1-a0/255.0) * *(col+2) + (1-a1/255.0)*(a0/255.0) * *(base_col+2) ) / ca +0.5; *(dst + 3) = n_byte(((a0 + a1) * 255 - a0 * a1) / 255); } else { *dst = *base_col; *(dst + 1) = *(base_col + 1); *(dst + 2) = *(base_col + 2); *(dst + 3) = *base_alpha; } dst += 4; col += col_step; base_col += col_step; alpha += alpha_step; base_alpha += base_alpha_step; } } } } } BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; } #ifdef _MANAGED #pragma managed(pop) #endif