// blend1.cpp : DLL アプリケーションのエントリ ポイントを定義します。 // #include "stdafx.h" #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 "hueh"; } 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) {//色相変更スライダー if (num_channel == 1) {// 表示・グレスケ用 const unsigned char* col_end = col + num_pixel * col_step; while (col < col_end) { *dst = *dst; 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) { if (*dst == *(dst + 1) && *dst == *(dst + 2)){ // RGB一致のグレーは変更しない *dst = *dst; *(dst + 1) = *(dst + 1); *(dst + 2) = *(dst + 2); } else { // RGBをHSVに変換 double hsv_h = 0 ; double hsv_s = 0 ; double hsv_v = 0 ; double a1 = *alpha / 255.0 * 359 ; double rgb_max = max(*(dst + 2), max(*(dst + 1), *dst)); double rgb_min = min(*(dst + 2), min(*(dst + 1), *dst)); // h if(rgb_max == *(dst + 2)){ // 赤が一番高いとき hsv_h = (int)(60 * (*(dst + 1) - *dst) / (rgb_max - rgb_min) + 360) % 360; } else if(rgb_max == *(dst + 1)){ // 緑が一番高いとき hsv_h = (60 * (*dst - *(dst + 2)) / (rgb_max - rgb_min)) + 120; } else if(rgb_max == *dst){ // 青が一番高いとき hsv_h = (60 * (*(dst + 2) - *(dst + 1)) / (rgb_max - rgb_min)) + 240; } hsv_h = (int)(hsv_h + a1 +360) % 360; // s hsv_s = (255 * ((rgb_max - rgb_min) / rgb_max)); // v hsv_v = rgb_max; // HSVをRGBに戻す int hi = 0; double f, p, q, t; hi = ((int)(hsv_h / 60)) % 6; f = hsv_h / 60 - hi; p = hsv_v * (1 - (hsv_s / 255)); q = hsv_v * (1 - f * (hsv_s / 255)); t = hsv_v * (1 - (1 - f) * (hsv_s / 255)); if (hi == 0){ *(dst + 2) = (int)hsv_v; *(dst + 1) = (int)t; *dst = (int)p; } else if (hi == 1){ *(dst + 2) = (int)q; *(dst + 1) = (int)hsv_v; *dst = (int)p; } else if (hi == 2){ *(dst + 2) = (int)p; *(dst + 1) = (int)hsv_v; *dst = (int)t; } else if (hi == 3){ *(dst + 2) = (int)p; *(dst + 1) = (int)q; *dst = (int)hsv_v; } else if (hi == 4){ *(dst + 2) = (int)t; *(dst + 1) = (int)p; *dst = (int)hsv_v; } else if (hi == 5){ *(dst + 2) = (int)hsv_v; *(dst + 1) = (int)p; *dst = (int)q; } } 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) { *dst = *base_col; *(dst + 1) = *base_alpha; } 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) { if (*base_col == *(base_col + 1) && *base_col == *(base_col + 2)){ // RGB一致のグレーは変更しない *dst = *base_col; *(dst + 1) = *(base_col + 1); *(dst + 2) = *(base_col + 2); *(dst + 3) = *base_alpha; } else { // RGBをHSVに変換 double hsv_h = 0 ; double hsv_s = 0 ; double hsv_v = 0 ; double a1 = *alpha / 255.0 * 359 ; double rgb_max = max(*(base_col + 2), max(*(base_col + 1), *base_col)); double rgb_min = min(*(base_col + 2), min(*(base_col + 1), *base_col)); // h if(rgb_max == *(base_col + 2)){ // 赤が一番高いとき hsv_h = (int)(60 * (*(base_col + 1) - *base_col) / (rgb_max - rgb_min) + 360) % 360; } else if(rgb_max == *(base_col + 1)){ // 緑が一番高いとき hsv_h = (60 * (*base_col - *(base_col + 2)) / (rgb_max - rgb_min)) + 120; } else if(rgb_max == *base_col){ // 青が一番高いとき hsv_h = (60 * (*(base_col + 2) - *(base_col + 1)) / (rgb_max - rgb_min)) + 240; } hsv_h = (int)(hsv_h + a1 +360) % 360; // s hsv_s = (255 * ((rgb_max - rgb_min) / rgb_max)); // v hsv_v = rgb_max; // HSVをRGBに戻す int hi = 0; double f, p, q, t; hi = ((int)(hsv_h / 60)) % 6; f = hsv_h / 60 - hi; p = hsv_v * (1 - (hsv_s / 255)); q = hsv_v * (1 - f * (hsv_s / 255)); t = hsv_v * (1 - (1 - f) * (hsv_s / 255)); if (hi == 0){ *(dst + 2) = (int)hsv_v; *(dst + 1) = (int)t; *dst = (int)p; *(dst + 3) = *base_alpha; } else if (hi == 1){ *(dst + 2) = (int)q; *(dst + 1) = (int)hsv_v; *dst = (int)p; *(dst + 3) = *base_alpha; } else if (hi == 2){ *(dst + 2) = (int)p; *(dst + 1) = (int)hsv_v; *dst = (int)t; *(dst + 3) = *base_alpha; } else if (hi == 3){ *(dst + 2) = (int)p; *(dst + 1) = (int)q; *dst = (int)hsv_v; *(dst + 3) = *base_alpha; } else if (hi == 4){ *(dst + 2) = (int)t; *(dst + 1) = (int)p; *dst = (int)hsv_v; *(dst + 3) = *base_alpha; } else if (hi == 5){ *(dst + 2) = (int)hsv_v; *(dst + 1) = (int)p; *dst = (int)q; *(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