白色背景についての、見た目を保ったまま png を透過させたいのですが、どんな方法がありますでしょうか。
ひとまず、手法、言語、ツール等は問いません。ただ、バッチ処理ができると、嬉しいです。
以下、状況です。
スキャンした印鑑の印影画像(赤)があります。白色部(紙)を透過させることは、あまり難しくはありません。選択して、透過色に設定します。
ところが、この画像を文字等に重ねると、ある問題が生じます。
0. (軽微な問題) 抜ききれなかった白色部が上書きされる
0. 印鑑で押印した場合、下の文字が見える(半透明)が、画像を重ねてしまうと、消えてしまう
どちらも、根本は同じ問題で、透過の設定が不十分であることです。
要するに、トーンカーブで紙は完全に白にしておいて、明度や輝度からアルファチャンネルを作ればよいのでしょうが、適当な方法を探すことができませんでした。
【Photoshop】写真の影を使った透過 / 明度からアルファチャンネル作成
透明度を計算してみよう / 黒と白の上にアルファ合成された色からの元の色と不透明度の計算ツール
のようなこと(後者は少し違いますが)が行えればよいと思っています。ただ、印字された時の色は、できるだけ保ちたいです。
よろしくお願い致します。
まず png ファイルを ppm ファイルにしておき、以下のようなプログラムで、ppm ファイルから 色情報の ppm と、アルファチャンネルの pgm を生成、最後に、それらを結合して透過 png を生成…としてみることはできました。
もっといい方法があれば、教えて下さい。
lang
1filename="a.png" 2base=`basename $filename .png` 3pngtopam $filename | pamtopnm -plain > ${base}.ppm 4./pnmalpha ${base}.ppm ${base}_col.ppm ${base}_alpha.pgm 5pnmtopng -force -alpha=${base}_alpha.pgm ${base}_col.ppm > ${base}_trans.png
lang
1#include<iostream> 2#include<fstream> 3#include<algorithm> 4 5int main(int argc, char **argv) { 6 if (argc < 4) { 7 std::cout << "too few arguments" << std::endl; 8 std::cout << "usage: src.ppm dst.ppm alpha.pgm" << std::endl; 9 return 1; 10 } 11 12 const std::string magic_ppm = "P3", magic_pgm = "P2"; 13 std::string magic; 14 std::ifstream ifs(argv[1]); 15 std::ofstream ofs_color(argv[2]), ofs_alpha(argv[3]); 16 int w, h, max_val; 17 int r, g, b, min_rgb; // current val 18 int nr, ng, nb, na; // new val 19 20 if (!ifs || !ofs_color || !ofs_alpha) { 21 std::cerr << "file open error" << std::endl; 22 return 1; 23 } 24 25 ifs >> magic; 26 if (magic != magic_ppm) { 27 std::cerr << "input file format error" << std::endl; 28 return 1; 29 } 30 ifs >> w >> h; 31 ifs >> max_val; 32 33 ofs_color << magic_ppm << std::endl; 34 ofs_color << w << " " << h << std::endl; 35 ofs_color << max_val << std::endl; 36 37 ofs_alpha << magic_pgm << std::endl; 38 ofs_alpha << w << " " << h << std::endl; 39 ofs_alpha << max_val << std::endl; 40 41 for (int i = 0; i < h; ++i) { 42 for (int j = 0; j < w; ++j) { 43 ifs >> r >> g >> b; 44 min_rgb = std::min(r, std::min(g, b)); 45 if (min_rgb == 0) { 46 na = max_val; 47 nr = r; 48 ng = g; 49 nb = b; 50 } else if (min_rgb == max_val) { 51 na = 0; 52 nr = max_val; 53 ng = max_val; 54 nb = max_val; 55 } else { 56 na = max_val - min_rgb; 57 nr = (r + na - max_val) * max_val / na; 58 ng = (g + na - max_val) * max_val / na; 59 nb = (b + na - max_val) * max_val / na; 60 } 61 ofs_color << nr << " " << ng << " " << nb << " "; 62 ofs_alpha << na << " "; 63 } 64 ofs_color << std::endl; 65 ofs_alpha << std::endl; 66 } 67 return 0; 68}
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/08/23 00:04