/* 2007/1/5
* c0104401 吉原美樹 * 土曜prog img_make.java * 写真(jpg)を読み込みサンプルを作成しpngファイルに出力する * * Ver.0.5 int型の引数で呼び出されるように修正 * Ver.0.8 "次へ"を設置(押すとhair_sample.pngを上書き保存) * Ver.1.0 "次へ"ボタンを破棄(画像の保存は変数で制御し * 一番最初とカラーパレットから色を選ぶ度に行う * 毎回jpgを読み込んでいたものを * 起動時に一度だけ読み込むように変更 * それに伴いアルファ値のセット・リセットを記述 * コメントを追加 * 範囲選択の部分を修正 * ドラッグ中に写真外に出た場合は写真のへりに点を取ったことにする * 変数の出力ファイル名(output_name)以外をprivate化 * Ver.1.2 コメントの追加 * アプレットでも画像を表示できるように */
import java.applet.Applet;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
public class img_make extends Applet{
/** * */
// シリアル番号 private static final long serialVersionUID = 1L;
// ----------------- 変数の宣言↓ここから↓ -----------------
// 顧客番号 private String name_id = "0000000000000.jpg"; // 初期値は0000000000000 private int nameid_num = 12 ; // 何桁か
// 出力するファイル名(外部から操作可能) String filename = "hair_sample.png" ;
// 表示 private Graphics2D g_base; private BufferedImage g_baseImage = null;
// ベース(全体を一枚の絵にしてから表示する) private Graphics2D base_draw; private BufferedImage baseImage = null;
// 写真の部分(ファイルに出力する) private Graphics2D pict_draw; private BufferedImage hairImage = null; private Image in_img ;
// 画面のサイズ private static int win_width = 750 ; // 横 private static int win_height = 440 ; // 縦
// トリミングや空白の数値 private int pict_left = 20 ; // 写真左部の空白 private int pict_top = 20 ; // 写真上部の空白 private int pict_width = 260 ; // 写真の横 private int pict_height = 400 ; // 写真の縦
private int colorbox_size = 100 ; // カラーパレットのひとつの升目の縦と横(正方形) private int colorbox_gap = 5; // カラーパレット同士の間の空白
// カラーパレット1左部↓ private int colorbox1_left = pict_left + pict_width + 40 ; // カラーパレット2左部↓ private int colorbox2_left = colorbox1_left + colorbox_size + colorbox_gap ; // カラーパレット3左部↓ private int colorbox3_left = colorbox2_left + colorbox_size + colorbox_gap ; // カラーパレット4左部↓ private int colorbox4_left = colorbox3_left + colorbox_size + colorbox_gap ;
//カラーパレット1~4上部↓ private int colorbox1_top = pict_top + 60 ;
// カラーパレット5左部↓ private int colorbox5_left = colorbox1_left ; // カラーパレット6左部↓ private int colorbox6_left = colorbox5_left + colorbox_size + colorbox_gap ; // カラーパレット7左部↓ private int colorbox7_left = colorbox6_left + colorbox_size + colorbox_gap ; // カラーパレット8左部↓ private int colorbox8_left = colorbox7_left + colorbox_size + colorbox_gap ;
// カラーパレット5~8上部↓ private int colorbox5_top = colorbox1_top + colorbox_size + colorbox_gap ;
// マウスの座標を読み込むための変数 private double mouseX = 0 ; // x座標 private double mouseY = 0 ; // y座標
// カラーリング指定の色宣言 private String what_color = "0x000000"; // これで指定(初期値は黒) // 上の段の四色 private String color_1 = "0xFF0000"; // 赤 private String color_2 = "0x000000"; // 黒 private String color_3 = "0xFFFF00"; // 黄 private String color_4 = "0x0000FF"; // 青
// 下の段の四色 private String color_5 = "0x999999"; // 灰 private String color_6 = "0x009933"; // 緑 private String color_7 = "0x663300"; // 茶 private String color_8 = "0xFFCCCC"; // ピンク
// 髪色の範囲が選択されているか否か private int hair_scope_num = 0 ; // 選択された点はいくつあるか(2未満では未選択と判定) private int hair_pointMax = 10000 ; // 点をいくつ使うか private int hairX[] = new int[hair_pointMax]; // 選択された点のx座標 private int hairY[] = new int[hair_pointMax]; // 選択された点のy座標
// 髪色の範囲を選択している最中か否か //(マウスのボタンが写真中で行われた場合にtrue、マウスのボタンが離されるとfalse) private boolean hair_scoping = false ; // 初期値は"選択中ではない" private boolean read_pict = true ; // 写真を背景に読み込むか
private double point_beginX; // 選択線の始点x座標 private double point_beginY; // 選択線の始点y座標 private double point_endX; // 選択線の終点x座標 private double point_endY; // 選択線の終点y座標
// 領域選択に使う変数 private int line_count = 0; private int line_every = 3; // 何回呼び出される毎にポイントを取得するか
// カラーパレットのボタンが押されたかどうか private boolean hair_coloring = false ;
// 画像を保存するかどうか private boolean pict_out = false ;
// 透過度を指定 private float alpha = 0.5f; // between 0.0f and 1.0f // セット private AlphaComposite alphaComposite_set = AlphaComposite.getInstance( AlphaComposite.SRC_OVER, alpha ); // リセット(不透明に戻す) private AlphaComposite alphaComposite_reset = AlphaComposite.getInstance( AlphaComposite.SRC_OVER, 1.0f ); int width_; int height_; MediaTracker tracker; // ----------------- 変数の宣言↑ここまで↑ -----------------
public void init() {
// タイマーの初期化
tracker = new MediaTracker(this);
// 画面をリサイズ
resize(win_width,win_height);
width_=getSize().width;
height_=getSize().height;
setBackground(Color.decode("0xFFFFFF"));
setForeground(Color.white);
g_baseImage = (BufferedImage) createImage(width_,height_); g_base = (Graphics2D) g_baseImage.getGraphics();
int i,j,id, ex_num = 0 ; // int変数を文字列に変換するための準備1
String ex_str;
ex_str = getParameter("id_name") ; // int変数を文字列に変換するための準備2
id = Integer.parseInt (ex_str); // 顧客番号をString型からint型に変換
// ファイル名の桁数(nameid_num)に足りない分の桁数を数える
if(id == 0){ // id番号が0のときは別処理
ex_num = nameid_num ;
}
else{// id番号が0より大きい場合
j = id ;
for(i=0;j>0;i++){// 桁数を数える
j = j/10 ;
ex_num = nameid_num - i;
}
}//else
name_id = ""; // name_idを空にする
for(i=0;i<ex_num-1;i++){ // 足りない分だけ頭に0を詰める
name_id = name_id + "0";
}
name_id = name_id + ex_str; // 受け取ったid番号を後ろにつける
// 一度だけhairImage_bufに写真を読み込んでおき
// 書き換えるときはhairImageの上にhairImage_bufを上書きする
in_img = getImage(getDocumentBase(),"data/"+name_id+".jpg");
tracker.addImage(in_img, 0);
// マウスがドラッグをしているときの動きを監視
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
// 髪色の範囲を選択中のときのみ実行する
if(hair_scoping){
mouseX = e.getX(); // x座標
mouseY = e.getY(); // y座標
if(mouseX < pict_left + 1){// x座標が範囲より左にあった
mouseX = pict_left + 1 ; // x座標を左縁にとる
}
else if(mouseX > pict_left + pict_width - 1){// x座標が範囲より右にあった
mouseX = pict_left + pict_width - 1 ;// x座標を右縁にとる
}
if(mouseY < pict_top + 1){// y座標が範囲より上にあった
mouseY = pict_top + 1 ;// y座標を上縁にとる
}
else if(mouseY > pict_top + pict_height - 1){// x座標が範囲より下にあった
mouseY = pict_top + pict_height - 1 ;// y座標を下縁にとる
}
line_count++; // 範囲の選択中にこの命令が何度呼び出されたかを加算
if(line_count%line_every == 0){// 何度か呼び出されるごとに点をとる
point_beginX = point_endX; // 始点のx座標(前回の終点のx座標)
point_beginY = point_endY; // 始点のy座標(前回の終点のy座標)
point_endX = mouseX - pict_left; // 終点のx座標
point_endY = mouseY - pict_top; // 終点のy座標
hairX[hair_scope_num] = (int)point_endX; // 選択点のx座標 hairY[hair_scope_num] = (int)point_endY; // 選択点のy座標 hair_scope_num++; // 次の選択点へ
// 点が移動していた場合だけ線を描く
// (始点のx座標と終点のx座標が一致しない
// または、始点のy座標と終点のy座標が一致しない)
if((point_beginX != point_endX)||(point_beginY != point_endY)){
repaint(); // 描画関数を呼び出す
}
}//if(line...
}//if(hair...
}
});
addMouseListener(new MouseAdapter() {
// マウスのボタン(左)が押された
public void mousePressed(MouseEvent e){
mouseX = e.getX(); // x座標
mouseY = e.getY(); // y座標
// --- 写真の中だった場合↓ここから↓ ---
if((mouseX > pict_left && mouseX < pict_left + pict_width)
&&(mouseY > pict_top && mouseY < pict_top + pict_height)){
// hair_scopingをtrueにすることで
// 髪色の範囲を選択中であることを示す
hair_scoping = true ;
// 初期化
hair_scope_num = 0; // 選択点を0に
read_pict = true ; // 写真を読み込む
hair_coloring = false ; // カラーパレット未選択
point_beginX = point_endX = mouseX - pict_left; // 始点x座標=終点x座標 point_beginY = point_endY = mouseY - pict_top; // 始点y座標=終点y座標
hairX[hair_scope_num] = (int)point_endX ; // 選択点のx座標
hairY[hair_scope_num] = (int)point_endY ; // 選択点のy座標
hair_scope_num++; // 次の選択点へ
}
// --- 写真の中だった場合↑ここまで↑ ---
// --- カラーパレットの上部中だった場合↓ここから↓ ---
else if(mouseY > colorbox1_top && mouseY < colorbox1_top + colorbox_size){
// カラーパレットの1の中だった場合
if(mouseX > colorbox1_left && mouseX < colorbox1_left + colorbox_size){
what_color = color_1 ;
read_pict = true ; // 写真を読み込む
hair_coloring = true ; // カラーパレットが選択された
repaint();
}
// カラーパレットの2の中だった場合
else if(mouseX > colorbox2_left && mouseX < colorbox2_left + colorbox_size){
what_color = color_2 ;
read_pict = true ; // 写真を読み込む
hair_coloring = true ; // カラーパレットが選択された
repaint();
}
// カラーパレットの3の中だった場合
else if(mouseX > colorbox3_left && mouseX < colorbox3_left + colorbox_size){
what_color = color_3 ;
read_pict = true ; // 写真を読み込む
hair_coloring = true ; // カラーパレットが選択された
repaint();
}
// カラーパレットの4の中だった場合
else if(mouseX > colorbox4_left && mouseX < colorbox4_left + colorbox_size){
what_color = color_4 ;
read_pict = true ; // 写真を読み込む
hair_coloring = true ; // カラーパレットが選択された
repaint();
}
}
// --- カラーパレットの上部中だった場合↑ここまで↑ ---
// --- カラーパレットの下部中だった場合↓ここから↓ ---
else if(mouseY > colorbox5_top && mouseY < colorbox5_top + colorbox_size){
// カラーパレットの5の中だった場合
if(mouseX > colorbox5_left && mouseX < colorbox5_left + colorbox_size){
what_color = color_5 ;
read_pict = true ; // 写真を読み込む
hair_coloring = true ; // カラーパレットが選択された
repaint();
}
// カラーパレットの6の中だった場合
else if(mouseX > colorbox6_left && mouseX < colorbox6_left + colorbox_size){
what_color = color_6 ;
read_pict = true ; // 写真を読み込む
hair_coloring = true ; // カラーパレットが選択された
repaint();
}
// カラーパレットの7の中だった場合
else if(mouseX > colorbox7_left && mouseX < colorbox7_left + colorbox_size){
what_color = color_7 ;
read_pict = true ; // 写真を読み込む
hair_coloring = true ; // カラーパレットが選択された
repaint();
}
// カラーパレットの8の中だった場合
else if(mouseX > colorbox8_left && mouseX < colorbox8_left + colorbox_size){
what_color = color_8 ;
read_pict = true ; // 写真を読み込む
hair_coloring = true ; // カラーパレットが選択された
repaint();
}
}
// --- カラーパレットの下部中だった場合↑ここまで↑ ---
}//mousePressed()
// マウスのボタン(左)が離された
public void mouseReleased(MouseEvent e){
// 髪色の範囲を選択中のときのみ実行する
if(hair_scoping){
point_beginX = point_endX;
point_beginY = point_endY;
point_endX = hairX[0]; // 選択範囲の基点を終点に(x座標)
point_endY = hairY[0]; // 選択範囲の基点を終点に(y座標)
repaint();
hair_scoping = false ; // 初期化(髪の範囲選択を終えた)
}//if(hair...
}//mouseReleased()
});//addMouseListener()
// baseImageは一回だけ作成される
baseImage = new BufferedImage(getWidth(), getHeight(),
BufferedImage.TYPE_INT_BGR);
// baseImageに手を加える宣言
base_draw = baseImage.createGraphics();
base_draw.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// hairImageの初期化(真っ黒)
hairImage = new BufferedImage(pict_width, pict_height,
BufferedImage.TYPE_INT_BGR);
// hairImageに手を加える宣言 pict_draw = hairImage.createGraphics(); pict_draw.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// 画面全体を白く塗りつぶす base_draw.setColor(Color.white); base_draw.fill(new Rectangle2D.Double(0, 0, win_width, win_height));
// 黒で文字を書く
base_draw.setColor(Color.black);
base_draw.setFont(new Font("Serif",Font.BOLD,30)); // フォントの設定
base_draw.drawString("カラーパレット",colorbox1_left,colorbox1_top-20);
// カラーパレット1 base_draw.setColor(Color.decode(color_1)); base_draw.fill(new Rectangle2D.Double(colorbox1_left, colorbox1_top, colorbox_size, colorbox_size)); // カラーパレット2 base_draw.setColor(Color.decode(color_2)); base_draw.fill(new Rectangle2D.Double(colorbox2_left, colorbox1_top, colorbox_size, colorbox_size)); // カラーパレット3 base_draw.setColor(Color.decode(color_3)); base_draw.fill(new Rectangle2D.Double(colorbox3_left, colorbox1_top, colorbox_size, colorbox_size)); // カラーパレット4 base_draw.setColor(Color.decode(color_4)); base_draw.fill(new Rectangle2D.Double(colorbox4_left, colorbox1_top, colorbox_size, colorbox_size));
// カラーパレット5 base_draw.setColor(Color.decode(color_5)); base_draw.fill(new Rectangle2D.Double(colorbox5_left, colorbox5_top, colorbox_size, colorbox_size)); // カラーパレット6 base_draw.setColor(Color.decode(color_6)); base_draw.fill(new Rectangle2D.Double(colorbox6_left, colorbox5_top, colorbox_size, colorbox_size)); // カラーパレット7 base_draw.setColor(Color.decode(color_7)); base_draw.fill(new Rectangle2D.Double(colorbox7_left, colorbox5_top, colorbox_size, colorbox_size)); // カラーパレット8 base_draw.setColor(Color.decode(color_8)); base_draw.fill(new Rectangle2D.Double(colorbox8_left, colorbox5_top, colorbox_size, colorbox_size));
// 一番初めは、画像を保存する pict_out = true ; }
public void start(){
try {// 画像ファイルが読み込まれるまで待つ
tracker.waitForAll();
} catch (InterruptedException e) {
}
}
public void update(Graphics g)
{// 再描画
paint(g);
}
// ---------------- 描画関数↓ここから↓ ----------------------------
public void paint(Graphics g){
int i;
g_base = (Graphics2D)g;
// ------------- 写真部分の描画↓ここから↓ ----------------
if(read_pict){// 最初と再描画する場合
// hairImageにhairImage_bufを上書き
pict_draw.drawImage(in_img, 0, 0, this);
// 写真の読み込みをしない(選択中は線を書き加えていくだけ)
read_pict = false ;
}
// カラーパレットのボタンが押された
if(hair_coloring){
pict_draw.setComposite( alphaComposite_set ); // 透過度をセット
pict_draw.setColor(Color.decode(what_color)); // 選択された色をセット
// 範囲選択済みの場合はポリゴンを作成し塗りつぶす
if(hair_scope_num>2){
// 新規オブジェクトの構築(ポリゴン)
GeneralPath hair_polygon = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
hair_polygon.moveTo(hairX[0], hairY[0]); // 基点を移動
for(i=1;i<hair_scope_num;i++){ // 点の数だけ繰り返す
// 前の点から現在の点へポリゴン
hair_polygon.lineTo(hairX[i],hairY[i]);
}
hair_polygon.closePath(); // ポリゴンを閉じる
pict_draw.fill(hair_polygon); // 塗りつぶす
}
// 範囲選択済みでない場合は写真全体を塗りつぶす
else{
pict_draw.fill(new Rectangle2D.Double(0, 0, pict_width, pict_height));
}
// 画像を保存する pict_out = true ; pict_draw.setComposite( alphaComposite_reset ); // 透過度をリセット }//if(hair...
// カラーパレットのボタンが押された以外で再描画
// (写真中でマウスのボタンが押され、髪色範囲指定の最中)
else{
BasicStroke wideStroke = new BasicStroke(2.0f);
pict_draw.setStroke(wideStroke);
pict_draw.setPaint(Color.red);
pict_draw.drawLine((int)point_beginX,(int)point_beginY,(int)point_endX,(int)point_endY);
}//else
// ------------- 写真部分の描画↑ここまで↑ ----------------
// 作成した写真(hairImage)をベース(baseImage)に貼り付ける base_draw.drawImage(hairImage, pict_top, pict_left, this); // ベース(baseImage)を表示する g_base.drawImage(baseImage, 0, 0, this);
if(pict_out){// 作成した写真(hairImage)を保存する
// 写真の保存をオフにする pict_out = false ; }//if } // ---------------- 描画関数↑ここまで↑ ----------------------------
}