001    
002    package com.rain;
003    
004    import java.io.*;
005    import java.util.*;
006    import java.lang.*;
007    import javax.servlet.http.*;
008    import javax.servlet.ServletInputStream;
009    import javax.imageio.*;
010    import javax.imageio.stream.*;
011    import java.awt.image.BufferedImage;
012    import java.awt.RenderingHints;
013    import java.awt.geom.AffineTransform;
014    import java.awt.Graphics2D;
015    import java.awt.image.*;
016    import java.awt.Color;
017    import java.awt.Font;
018    import java.awt.color.ColorSpace;
019    
020    /**  
021     * À̹ÌÁö Çڵ鸵 
022     * @version 1.0
023     * @author http://cafen.net (outmind@cafen.net)
024     */
025    public class rainImage {
026    
027    /**  
028     * ±âº» À̹ÌÁö
029     */
030            public BufferedImage img;
031    
032    /**  
033     * text_x ¸¶Áö¸· TEXT XÁÂÇ¥
034     * text_y ¸¶Áö¸· TEXT YÁÂÇ¥
035     */
036            public int text_x = 0, text_y = 0;
037    
038    /**  
039     * max_x À̹ÌÁö ÃÖ´ë °¡·Î
040     * max_y À̹ÌÁö ÃÖ´ë ¼¼·Î
041     */
042            public int max_x = 1024, max_y = 4000;
043    
044    /**  
045     * À̹ÌÁö ±âº» °æ·Î
046     */
047            public String base_root = null;
048    
049    /**
050     * »ý¼ºÀÚ
051     */
052            public rainImage(){}
053    
054    /**
055     * »ý¼ºÀÚ
056     * @param  destWidth  À̹ÌÁö °¡·Î
057     * @param  destHeight À̹ÌÁö ¼¼·Î
058     */
059            public rainImage(int destWidth, int destHeight){
060                    this.img = this.getImg(destWidth, destHeight);
061            }
062    
063    /**
064     *  Graphics2D °¡Á®¿À±â
065     * @return  Graphics2D
066     */
067            public Graphics2D getGraphic(){
068                     return this.img.createGraphics();
069            }
070    
071    /**
072     *  ±âº» ÀÛ¾÷ °ø°£ °¡Á®¿À±â
073     * @return  base Root dir
074     */
075            public String getBaseRoot(){
076                    if (this.base_root == null)
077                            this.base_root = rainUtil.getConf("path_uploads");
078                    return this.base_root;
079            }
080    
081    /**
082     *  À̹ÌÁö »ý¼º
083     * @param  w  À̹ÌÁö °¡·Î
084     * @param  h À̹ÌÁö ¼¼·Î
085     * @return  BufferedImage
086     */
087            public BufferedImage getImg(int w, int h){
088                    return new BufferedImage(w,h,BufferedImage.TYPE_INT_ARGB);
089            }
090    
091    /**
092     *  À̹ÌÁö ºÒ·¯¿À±â
093     * @param  fileName  À̹ÌÁö ÆÄÀϸí
094     * @param  onErrorimg À̹ÌÁö °¡Á®¿À±â ½ÇÆÐ½Ã °¡Á®¿Ã À̹ÌÁö
095     * @return  BufferedImage
096     */
097            public BufferedImage load(String fileName, String onErrorimg ){
098                    BufferedImage img = this.getImg(100,100);
099            try {
100                    FileInputStream src = new FileInputStream(new File(this.getBaseRoot() + fileName));
101                            BufferedImage tmp = ImageIO.read(src);
102                            src.close();
103                            if (tmp.getWidth() > this.max_x || tmp.getHeight() > this.max_y) {
104                                    int resize_w = 0,resize_h = 0;
105                                    if (this.max_x < tmp.getWidth()) {
106                                            resize_w = this.max_x;
107                                            resize_h = (int)((double)this.max_x/(double)tmp.getWidth() * tmp.getHeight());
108                                    } else {
109                                            resize_w = (int)((double)this.max_y/(double)tmp.getHeight() * tmp.getWidth());
110                                            resize_h = this.max_y;
111                                    }
112                                    img = this.resize(tmp, resize_w, resize_h);
113                            }
114                            if (tmp.getType() != BufferedImage.TYPE_INT_ARGB) {
115                                    img = this.getImg(tmp.getWidth(),tmp.getHeight());
116                                    Graphics2D g = img.createGraphics();
117                                    g.drawImage(tmp, 0, 0, tmp.getWidth(), tmp.getHeight(), null);
118                            } else
119                                    img = tmp;
120            } catch(Exception e) {
121                    if (!onErrorimg.equals(""))
122                                    img = this.load(onErrorimg,"");
123            }
124                    return img;
125            }
126    
127    /**
128     *  À̹ÌÁö ºÒ·¯¿À±â
129     * @param  fileName  À̹ÌÁö ÆÄÀϸí
130     * @return  BufferedImage
131     */
132            public BufferedImage load(String fileName){
133                    return this.load(fileName,"");
134            }
135    
136    /**
137     *  À̹ÌÁö ÀÚ¸£±â
138     * @param  img  À̹ÌÁö
139     * @param  rate  °¡·Î¼¼·Î ºñÀ²
140     * @param  pos  ±âÁØÀ§Ä¡ (0 : Á»ó´Ü, 1: Áß°£»ó´Ü, 2: ¿ì»ó´Ü, 3 : ÁÂÁß°£, 4 : Áß°£Áß°£, 5 : ¿ìÁß°£, 6 : ÁÂÇÏ´Ü, 7 : Áß°£ÇÏ´Ü, 8: ¿ìÇÏ´Ü)
141     * @return  BufferedImage
142     */
143            public BufferedImage trim(BufferedImage img, double rate, int pos){
144                    int ow , tw ;
145                    ow = tw = img.getWidth();
146                    int oh , th;
147                    oh = th = img.getHeight();
148                    if ((double) ow/oh >= rate)
149                            tw = (int)((double)oh * rate);
150                    else
151                            th = (int)((double)ow / rate);
152                    int padding_x = 0, padding_y = 0;
153                    switch(pos) {
154                            case 0 :
155                                    padding_x = 0;
156                                    padding_y = 0;
157                                    break;
158                            case 1 :
159                                    padding_x = (int)((ow - tw)/2);
160                                    padding_y = 0;
161                                    break;
162                            case 2 :
163                                    padding_x = (ow - tw);
164                                    padding_y = 0;
165                                    break;
166                            case 3 :
167                                    padding_x = 0;
168                                    padding_y = (int)((oh - th)/2);
169                                    break;
170                            case 4 :
171                                    padding_x = (int)((ow - tw)/2);
172                                    padding_y = (int)((oh - th)/2);
173                                    break;
174                            case 5 :
175                                    padding_x = ow - tw;
176                                    padding_y = (int)((oh - th)/2);
177                                    break;
178    
179                            case 6 :
180                                    padding_x = 0;
181                                    padding_y = oh - th;
182                                    break;
183                            case 7 :
184                                    padding_x = (int)((ow - tw)/2);
185                                    padding_y = oh - th;
186                                    break;
187                            case 8 :
188                                    padding_x = ow - tw;
189                                    padding_y = oh - th;
190                                    break;
191                    }
192                    return img.getSubimage(padding_x,padding_y,tw,th);
193            }
194    
195    /**
196     *  ¼¶³×ÀÏ À̹ÌÁö ¸¸µé±â thumb/À̹ÌÁöÆÄÀϰæ·Î¸í_À̹ÌÁöÈ¿°ú.png 
197     *  F([a-z]+)([0-9]+)([MDT])S=(.+)= : 1 ÇÁ·¹ÀÓÀû¿ë (base, box, cap, cross, dashed, rain, saw, shadow, shasowbox)
198     *  F([a-z]+)([0-9]+)([MDT])S=(.+)= : 2 ÇÁ·¹ÀÓ ¿©¹é
199     *  F([a-z]+)([0-9]+)([MDT])S=(.+)= : 3 »çÁø ÃÔ¿µÁ¤º¸( M : »çÁø±â±âÁ¾, D:ÃÔ¿µÀÏÀÚ, T : ³ëÃâÁ¤º¸)
200     *  F([a-z]+)([0-9]+)([MDT])S=(.+)= : 4 »çÁø½ÎÀÎÃß°¡
201     *  R[0-3] : »çÁøÈ¸Àü [0 : ÀÚµ¿È¸Àü, 1: 90µµ, 2: 180µµ, 3: 270 µµ]
202     *  M([0-9]+)  : °¡·Î ÃÖ´ë±æÀÌ
203     *  A([0-9]+)  : »ö»ó º¯°æ
204     *  T([0-9]+)  : »çÁø Æ®¸²¹Ö, 100À» ±âÁØÀ¸·Î 100 ÀÌÇÏ´Â ¼¼·Î°¡ Å«»çÁø, 100 ÀÌ»óÀº °¡·Î°¡ Å«»çÁø 50 ÀÇ °æ¿ì °¡·Î/¼¼·Î ÀÌ 0.5 À» ¶æÇÔ
205     *  G  : ±×·¹ÀÌ ½ºÄÉÀÏ
206     *  N  : ³×°¡Æ¼ºê»çÁø
207     *  B([0-9]+)  : ºí·¯ ¹× »þÆÝ È¿°ú 10À» ±âÁØÀ¸·Î 10 ÀÌÇÏ´Â ºí·¯, 10 ÀÌ»óÀº »çÆÝ 
208     *  S([0-9]+)  : »þÆÝ È¿°ú(¹Ì»ç¿ë¿¹Á¤)
209     *  E([0-9]+)  : ¿¡Áö È¿°ú(¼ýÀÚ°¡ Ŭ¼ö·Ï ¼±ÀÌ ºÐ¸íÇÔ)
210     *  W([0-9]+)  : È­ÀÌÆ® ¹ß¶õ½º (100 À» ±âÁØÀ¸·Î 100 ÀÌÇÏ´Â ¾îµÓ°Ô 100 ÀÌ»óÀº ¹à°Ô
211     *  C([0-9]+)  : ÄÜÆ®¶ó½ºÆ® (100 À» ±âÁØÀ¸·Î 100 ÀÌÇÏ´Â ¼±¸íÇÏ°Ô 100 ÀÌ»óÀº ¸ðÈ£ÇϰÔ
212     * @param  fileName  ¼¶³×ÀÏ ¸í 
213     * @return  ¼º°ø¿©ºÎ
214     */
215            public boolean makeThumb(String fileName){
216                    String img_name = "", imgeffect = "", frameeffect = "",  skineffect = "", img_type = "";
217                    rainExif exif = null;
218                    if ((new File(this.getBaseRoot() + fileName)).exists()) {
219                            return true;
220                    } else {
221                            String render_server = rainUtil.getConf("domain_render");
222                            if (!render_server.equals("")) {
223                                    rainFile remotefile = new rainFile(this.getBaseRoot());
224                                    String tmp_filename = remotefile.remote_Copy(render_server+"thumb/"+fileName, "junk/", "tmp");
225                                    if (tmp_filename.equals("")  || !rainUtil.file_exists(tmp_filename)) 
226                                            tmp_filename = remotefile.remote_Copy(render_server+"thumb/"+fileName, "junk/", "tmp");
227                                    if (!tmp_filename.equals("") && rainUtil.file_exists(tmp_filename)) {
228                                            if (rainUtil.checkDir(this.getBaseRoot(), fileName)) 
229                                                    rainUtil.rename(tmp_filename, fileName);
230                                    }
231                                    if (rainUtil.file_exists(fileName)) 
232                                            return true;
233                                    else
234                                            return false;
235                            } else {
236                                    Vector reg = new Vector();
237                                    if (rainUtil.find("^thumb/(.+)_([=a-zA-Z0-9_]+)\\.(png|jpg|gif)$", fileName, reg) || rainUtil.find("^(.+)_([=a-zA-Z0-9_]+)\\.(png|jpg|gif)$", fileName, reg)) {
238                                            img_name = reg.get(1).toString();
239                                            imgeffect = reg.get(2).toString();
240                                            img_type = reg.get(3).toString();
241                                            if (rainUtil.find("(.*)(K[0-9]+.*)", imgeffect, reg)) {
242                                                    imgeffect = reg.get(1).toString();
243                                                    skineffect = reg.get(2).toString();
244                                            } else if (rainUtil.find("(.+)(F[a-z]+[0-9]+.+)", imgeffect, reg)) {
245                                                    imgeffect = reg.get(1).toString();
246                                                    frameeffect = reg.get(2).toString();
247                                            }
248                                            if (rainUtil.find("R0", imgeffect)) {
249                                                    exif = new rainExif(img_name);  
250                                                    imgeffect = rainUtil.replace("R0", "R" + exif.getRotate(), imgeffect);
251                                            }
252                                            BufferedImage img = this.load(img_name, "imgstyle/img_error.jpg");
253                                            if (img.getWidth() > 1024)
254                                                    img = this.resize(img, 1024);
255                                            if (!imgeffect.equals(""))
256                                                    img = this.getImgEffect(img, imgeffect);
257                                            if (!skineffect.equals("")) {
258                                                    if (exif == null)
259                                                            exif = new rainExif(img_name);  
260                                                    img = this.getSkinEffect(img, skineffect, exif);
261                                            } else if (!frameeffect.equals("")) {
262                                                    if (exif == null)
263                                                            exif = new rainExif(img_name);  
264                                                    img = this.getFrameEffect(img, frameeffect, exif);
265                                            }
266                                            this.img = img;
267                                            if (this.save(fileName, img_type)) {
268                                                    if (rainUtil.find("^thumb/",fileName)) {
269                                                            rainFileManager fm = new rainFileManager(img_name);
270                                                            fm.add(fileName);
271                                                    }
272                                                    return true;
273                                            } else 
274                                                    return false;
275                                    } else 
276                                            return false;
277                            }
278                    }
279            }               
280            
281    /**
282     *  ¼¶³×ÀÏ À̹ÌÁö ¸¸µé°í À¥À¸·Î Àü¼Û
283     * @param  fileName  ¼¶³×ÀÏ ¸í
284     * @param  response  HttpServletResponse
285     */
286            public void showThumb(String fileName, HttpServletResponse response){
287                    if (this.makeThumb(fileName))
288                            this.show(fileName,response);
289            }
290    
291    /**
292     *  ÇÁ·¹ÀÓ È¿°ú
293     *  F([a-z]+)([0-9]+)([MDT])[SB]=(.+)= : 1 ÇÁ·¹ÀÓÀû¿ë (base, box, cap, cross, dashed, rain, saw, shadow, shasowbox)
294     *  F([a-z]+)([0-9]+)([MDT])[SB]=(.+)= : 2 ÇÁ·¹ÀÓ ¿©¹é
295     *  F([a-z]+)([0-9]+)([MDT])[SB]=(.+)= : 3 »çÁø ÃÔ¿µÁ¤º¸( M : »çÁø±â±âÁ¾, D:ÃÔ¿µÀÏÀÚ, T : ³ëÃâÁ¤º¸)
296     *  F([a-z]+)([0-9]+)([MDT])[SB]=(.+)= : 4 »çÁø½ÎÀÎÃß°¡ S : °ü¸®ÀÚ°¡ ÁöÁ¤¼º ¾Õ÷ÀÚ µÚ÷ÀÚ Ãß°¡, B: base64 ·Î encode ½ÃŲ ¹®ÀÚ¿­
297     * @param  img  ´ë»ó À̹ÌÁö
298     * @param  effect  ÇÁ·¹ÀÓÈ¿°ú
299     * @param  exif  »çÁøÀÇ Exif Á¤º¸
300     * @return  BufferedImage
301     */
302            public BufferedImage getFrameEffect(BufferedImage img, String effect, rainExif exif){
303                    String img_style = "", sign = "", pic_modelinfo = "", pic_dateinfo = "", pic_takeinfo = "";
304                    String fontcolor = "#464646";
305                    int addheight = 0, addwidth = 0, img_padding = 0;
306                    Vector reg = new Vector();
307                    if (rainUtil.find("F([a-z]+)([0-9]+)", effect, reg)) {
308                            img_style = reg.get(1).toString();
309                            img_padding = rainUtil.string2Int(reg.get(2).toString());
310                            addwidth = addheight += img_padding * 2;
311                    }
312                    if (rainUtil.find("S=([a-zA-Z0-9=]+)=", effect, reg)) {
313                            effect = rainUtil.replace("S="+reg.get(1).toString() + "=","",effect);
314                            sign = this.getSign(reg.get(1).toString());
315                    } else if (rainUtil.find("B=([a-zA-Z0-9=]+)=", effect, reg)) {
316                            effect = rainUtil.replace("B="+reg.get(1).toString() + "=","",effect);
317                            sign = rainUtil.base64_decode(reg.get(1).toString());
318                    }
319                    if (!sign.equals(""))
320                            addheight += 17;
321                    if (rainUtil.find("M", effect)) {
322                            pic_modelinfo = exif.getModel();
323                            if (!pic_modelinfo.equals(""))
324                                    addheight += 17;
325                    }
326                    if (rainUtil.find("D", effect)) {
327                            pic_dateinfo = exif.getDatetime();
328                            if (!pic_dateinfo.equals(""))
329                                    addheight += 17;
330                    }
331                    if (rainUtil.find("T", effect)) {
332                            pic_takeinfo = exif.getInfo();
333                            if (!pic_takeinfo.equals(""))
334                                    addheight += 17;
335                    }
336    
337                    int frmWidth = img.getWidth() +addwidth ;
338                    int frmHeight = img.getHeight() + addheight;
339                    this.img = this.getImg(frmWidth, frmHeight);
340                    if (!img_style.equals("") && !img_style.equals("none"))
341                            this.setFrame(img_style);
342                    this.setImg(img, img_padding);
343                    if (!sign.equals("")) 
344                            this.setText(sign, fontcolor);
345                    if (!pic_modelinfo.equals("")) 
346                            this.setText(pic_modelinfo, fontcolor);
347                    if (!pic_takeinfo.equals("")) 
348                            this.setText(pic_takeinfo, fontcolor);
349                    if (!pic_dateinfo.equals("")) 
350                            this.setText(pic_dateinfo, fontcolor);
351                    return this.img;
352            }
353    
354            /**
355             *  ½ºÅ² È¿°ú
356             *  K([a-z]+)([0-9]+)([MDT])[SB]=(.+)= : 1 ÇÁ·¹ÀÓÀû¿ë (base, box, cap, cross, dashed, rain, saw, shadow, shasowbox)
357             *  K([a-z]+)([0-9]+)([MDT])[SB]=(.+)= : 2 ÇÁ·¹ÀÓ ¿©¹é
358             *  K([a-z]+)([0-9]+)([MDT])[SB]=(.+)= : 3 »çÁø ÃÔ¿µÁ¤º¸( M : »çÁø±â±âÁ¾, D:ÃÔ¿µÀÏÀÚ, T : ³ëÃâÁ¤º¸)
359             *  K([a-z]+)([0-9]+)([MDT])[SB]=(.+)= : 4 »çÁø½ÎÀÎÃß°¡ S : °ü¸®ÀÚ°¡ ÁöÁ¤¼º ¾Õ÷ÀÚ µÚ÷ÀÚ Ãß°¡, B: base64 ·Î encode ½ÃŲ ¹®ÀÚ¿­
360             * @param  img  ´ë»ó À̹ÌÁö
361             * @param  effect  ÇÁ·¹ÀÓÈ¿°ú
362             * @param  exif  »çÁøÀÇ Exif Á¤º¸
363             * @return  BufferedImage
364            */
365            public BufferedImage getSkinEffect(BufferedImage img, String effect, rainExif exif){
366                    String img_style = "", sign = "", pic_modelinfo = "", pic_dateinfo = "", pic_takeinfo = "";
367                    String fontcolor = "#464646";
368                    Vector reg = new Vector();
369                    if (rainUtil.find("K([0-9]+)", effect, reg)) 
370                            img_style = reg.get(1).toString();
371                    if (rainUtil.find("S=([a-zA-Z0-9=]+)=", effect, reg)) {
372                            effect = rainUtil.replace("S="+reg.get(1).toString() + "=","",effect);
373                            sign = this.getSign(reg.get(1).toString());
374                    } else if (rainUtil.find("B=([a-zA-Z0-9=]+)=", effect, reg)) {
375                            effect = rainUtil.replace("B="+reg.get(1).toString() + "=","",effect);
376                            sign = rainUtil.base64_decode(reg.get(1).toString());
377                    }
378                    if (rainUtil.find("M", effect)) 
379                            pic_modelinfo = exif.getModel();
380                    if (rainUtil.find("D", effect)) 
381                            pic_dateinfo = exif.getDatetime();
382                    if (rainUtil.find("T", effect)) 
383                            pic_takeinfo = exif.getInfo();
384    
385                    String[] text = new String[] {"","","",""};
386                    if (!sign.equals(""))
387                            text[0] = sign;
388                    if (!pic_modelinfo.equals(""))
389                            text[1] = pic_modelinfo;
390                    if (!pic_takeinfo.equals(""))
391                            text[2] = pic_takeinfo;
392                    if (!pic_dateinfo.equals(""))
393                            text[3] = pic_dateinfo;
394                    if (!text[0].equals("") ||!text[1].equals("") || !text[2].equals("") || !text[3].equals(""))
395                            img = this.addText(img, text, 5);
396                    if (!img_style.equals(""))
397                            img = this.setSkin(img, img_style);
398                    return img;
399            }
400    
401    /**
402     *  À̹ÌÁö ½ÎÀÎ ¹®ÀÚ °¡Á®¿À±â
403     * @param  sign  ±âº» ¹®ÀÚ
404     * @return  À̹ÌÁö½ÎÀÎ
405     */
406            public String getSign(String sign){
407                    return rainUtil.getConf("imgsign_pre") + sign + rainUtil.getConf("imgsign_tail");
408            }       
409            
410    /**
411     *  À̹ÌÁö È¿°úÁÖ±â
412     *  R[0-3] : »çÁøÈ¸Àü [0 : ÀÚµ¿È¸Àü, 1: 90µµ, 2: 180µµ, 3: 270 µµ]
413     *  M([0-9]+)  : °¡·Î ÃÖ´ë±æÀÌ
414     *  A([0-9]+)  : »ö»ó º¯°æ
415     *  T([0-9]+)  : »çÁø Æ®¸²¹Ö, 100À» ±âÁØÀ¸·Î 100 ÀÌÇÏ´Â ¼¼·Î°¡ Å«»çÁø, 100 ÀÌ»óÀº °¡·Î°¡ Å«»çÁø 50 ÀÇ °æ¿ì °¡·Î/¼¼·Î ÀÌ 0.5 À» ¶æÇÔ
416     *  G  : ±×·¹ÀÌ ½ºÄÉÀÏ
417     *  N  : ³×°¡Æ¼ºê»çÁø
418     *  B([0-9]+)  : ºí·¯ ¹× »þÆÝ È¿°ú 10À» ±âÁØÀ¸·Î 10 ÀÌÇÏ´Â ºí·¯, 10 ÀÌ»óÀº »çÆÝ 
419     *  S([0-9]+)  : »þÆÝ È¿°ú(¹Ì»ç¿ë¿¹Á¤)
420     *  E([0-9]+)  : ¿¡Áö È¿°ú(¼ýÀÚ°¡ Ŭ¼ö·Ï ¼±ÀÌ ºÐ¸íÇÔ)
421     *  W([0-9]+)  : È­ÀÌÆ® ¹ß¶õ½º (100 À» ±âÁØÀ¸·Î 100 ÀÌÇÏ´Â ¾îµÓ°Ô 100 ÀÌ»óÀº ¹à°Ô
422     *  C([0-9]+)  : ÄÜÆ®¶ó½ºÆ® (100 À» ±âÁØÀ¸·Î 100 ÀÌÇÏ´Â ¼±¸íÇÏ°Ô 100 ÀÌ»óÀº ¸ðÈ£ÇϰÔ
423     * @param  img  ´ë»ó À̹ÌÁö
424     * @param  effect  À̹ÌÁö È¿°ú
425     * @return  BufferedImage
426     */
427            public BufferedImage getImgEffect(BufferedImage img, String effect){
428                    Vector reg = new Vector();
429                    if (rainUtil.find("R([0-9])", effect, reg)) 
430                            img  = this.setRotate(img, rainUtil.string2Int(reg.get(1).toString()));
431                    if (rainUtil.find("M([0-9]+)", effect, reg)) 
432                            img  = this.resize(img, rainUtil.string2Int(reg.get(1).toString()));
433                    int sat = 100, hue = 0 , bri = 100;
434                    if (rainUtil.find("A([0-9]+)", effect, reg)) 
435                            sat = rainUtil.string2Int(reg.get(1).toString());
436                    if (rainUtil.find("H([0-9]+)", effect, reg)) 
437                            hue = rainUtil.string2Int(reg.get(1).toString());
438                    if (rainUtil.find("W([0-9]+)", effect, reg)) 
439                            bri = rainUtil.string2Int(reg.get(1).toString());
440                    if (sat != 100 || hue != 0) 
441                            img  = this.effectHSB(img, hue,sat, bri);
442                    else if(bri != 100) 
443                            img  = this.effectBrighten(img, bri);
444    
445                    if (rainUtil.find("T([0-9]+)", effect, reg)) 
446                            img  = this.trim(img, rainUtil.string2Int(reg.get(1).toString())/100, 4);       
447                    if (rainUtil.find("G", effect, reg)) 
448                            img  = this.effectGray(img);    
449                    if (rainUtil.find("N", effect, reg)) 
450                            img  = this.effectReverse(img); 
451                    if (rainUtil.find("B([0-9]+)", effect, reg)) 
452                            img  = this.effectBlur(img, rainUtil.string2Int(reg.get(1).toString()));
453                    if (rainUtil.find("S([0-9])", effect, reg)) 
454                            img  = this.effectSharpen(img, rainUtil.string2Int(reg.get(1).toString()));
455                    if (rainUtil.find("E([0-9])", effect, reg)) 
456                            img  = this.effectEdge(img, rainUtil.string2Int(reg.get(1).toString()));
457                    if (rainUtil.find("C([0-9]+)", effect, reg)) 
458                            img  = this.effectContrast(img, rainUtil.string2Int(reg.get(1).toString()));
459                    return img;
460            }       
461    
462    /**
463     *  À̹ÌÁö ÀÌÆåÆ®ÁÖ±â
464     * @param  img  ´ë»ó À̹ÌÁö
465     * @param  lookupTable  ÂüÁ¶ Å×À̺í
466     * @return  BufferedImage
467     */
468            public BufferedImage effectEnd(BufferedImage img, LookupTable lookupTable){
469                    BufferedImage tmpimg = this.getImg(img.getWidth(),img.getHeight());
470                    LookupOp lop = new LookupOp(lookupTable, null);
471                    lop.filter(img,tmpimg);
472                    return tmpimg;
473            }
474    
475    /**
476     *  Ä¿³Ú °¡Á®¿À±â
477     * @param  kernel_type  Ä¿³ÚÇüÅÂ
478     * @param  level  ÂüÁ¶ ·¹º§
479     * @return  Kernel
480     */
481            public Kernel getKernel(String kernel_type, float level) {
482                    float[] data;
483                    
484                    if (kernel_type.equals("B")) 
485                            data = new float[]{0.0625f, 0.125f, 0.0625f, 0.125f, 0.25f, 0.125f,0.0625f, 0.125f, 0.0625f};
486                    else if (kernel_type.equals("S"))
487                            data = new float[]{0.0f , -0.125f , 0.0f , -0.125f ,  1.5f , -0.125f , 0.0f , -0.125f ,  0.0f};
488                    else 
489                            data = new float[]{2.0f, 0.0f, -2.0f, 2.0f, 1.0f, -2.0f, 2.0f , 0.0f ,-2.0f};
490    
491                    if (level == 1f)
492                            return new Kernel(3, 3, data);
493                    else {
494                            for(int i = 0; i < data.length; i++) 
495                                    data[i] =data[i] + (data[i] - 1f/9f) * (float)(level - 1f);
496                            return new Kernel(3, 3, data);
497                    }
498            }
499    
500    /**
501     *  ¼¼ÇÇ¾Æ È¿°úÁÖ±â
502     * @param  img  ´ë»ó À̹ÌÁö
503     * @param  base_color  ÂüÁ¶»ö»ó
504     * @return  BufferedImage
505     */
506            public BufferedImage effectSepia(BufferedImage img, String base_color){
507                    int[] rgb = this.hex2Int(base_color);
508                    byte[] red_table = new byte[256];
509                    byte[] green_table = new byte[256];
510                    byte[] blue_table = new byte[256];
511                    byte[] alpha_table = new byte[256];
512                    for(int i = 0; i < 256; i++) {
513                            red_table[i] = (byte)(i + (255 - (float)i)*(float)rgb[0]/255.0);
514                            green_table[i] = (byte)(i + (255 - (float)i)*(float)rgb[1]/255.0);
515                            blue_table[i] = (byte)(i + (255 - (float)i)*(float)rgb[2]/255.0);
516                            alpha_table[i] = (byte)i;
517                    }
518                    byte[][] lookup = new byte[][]{red_table, green_table, blue_table,alpha_table};
519                    return this.effectEnd(img, new ByteLookupTable(0, lookup));
520            }
521    
522    /**
523     *  ¿¡Áö È¿°úÁÖ±â
524     * @param  img  ´ë»ó À̹ÌÁö
525     * @param  rate  ÂüÁ¶ºñÀ²
526     * @return  BufferedImage
527     */
528            public BufferedImage effectEdge(BufferedImage img, int rate){
529                    if (rate == 0) return img;
530                    BufferedImage tmpimg = this.getImg(img.getWidth(),img.getHeight());
531                    Kernel kernel = this.getKernel("E", (float)rate);
532                    ConvolveOp convolve = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP,null);
533                    convolve.filter(img,tmpimg);
534                    rate--;
535                    return this.effectEdge(tmpimg, rate);
536            }
537    
538    /**
539     *  »ö»ó È¿°úÁÖ±â
540     * @param  img  ´ë»ó À̹ÌÁö
541     * @param  rate  ÂüÁ¶ºñÀ²
542     * @return  BufferedImage
543     */
544            public BufferedImage effectColor(BufferedImage img, int rate){
545                    rate = rate - 100;
546                    byte reverse[] = new byte[256];
547                    for (int i = 0; i < 256; i++) {
548                            reverse[i] = (byte) this.getSafeColor(i + rate);
549                    }
550                    return this.effectEnd(img, new ByteLookupTable(0, reverse));
551            }
552    
553    
554    /**
555     *  äµµ, Hue È¿°úÁÖ±â
556     * @param  img  ´ë»ó À̹ÌÁö
557     * @param  sat_rate  äµµÂüÁ¶ºñÀ² 
558     * @param  hue_rate  HueÂüÁ¶ºñÀ² 
559     * @return  BufferedImage
560    */
561            public BufferedImage effectHSB(BufferedImage img, int hue_rate, int sat_rate,int bri_rate){
562                    bri_rate = bri_rate - 100;
563                    sat_rate = sat_rate - 100;
564                    if (sat_rate == 0 && hue_rate == 0 && bri_rate == 0) return img;
565                    float float_sat = (float)sat_rate/100.0f;
566                    float float_bri = (float)bri_rate/100.0f;
567                    float float_hue = (float)hue_rate/180.0f;
568    
569                    for (int x = 0; x < img.getWidth() ; ++x) {
570                            for (int y = 0; y < img.getHeight(); ++y) {
571                                    Color col = new Color(img.getRGB(x,y));
572                                    float[] hsb;
573                                    hsb = Color.RGBtoHSB(col.getRed(), col.getGreen(), col.getBlue(), null);
574                                    float mod_hue = Math.max(Math.min(hsb[0]+float_hue, 1.0f),0.0f);
575                                    float mod_sat = Math.max(Math.min(hsb[1]+ hsb[1]*float_sat, 1.0f),0.0f);
576                                    float mod_bri = Math.max(Math.min(hsb[2]+  hsb[2]*float_bri, 1.0f),0.0f);
577                                    col = Color.getHSBColor(mod_hue , mod_sat, mod_bri) ;
578                                    img.setRGB(x,y,col.hashCode());
579                            }
580                    }
581                    return img;
582            }
583    
584    /**
585     *  ºí·¯ È¿°úÁÖ±â
586     * @param  img  ´ë»ó À̹ÌÁö
587     * @param  rate  ÂüÁ¶ºñÀ²
588     * @return  BufferedImage
589     */
590            public BufferedImage effectBlur(BufferedImage img, int rate){
591                    rate = rate - 10;
592                    if (rate == 0) return img;
593                    if (rate > 0) {
594                            Kernel kernel = this.getKernel("S", 1);
595                            while(rate > 0) {
596                                    BufferedImage tmpimg = this.getImg(img.getWidth(),img.getHeight());
597                                    ConvolveOp convolve = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP,null);
598                                    convolve.filter(img, tmpimg);
599                                    rate--;
600                                    img = tmpimg;
601                            }
602                    } else {
603                            Kernel kernel = this.getKernel("B", 1);
604                            while(rate < 0) {
605                                    BufferedImage tmpimg = this.getImg(img.getWidth(),img.getHeight());
606                                    ConvolveOp convolve = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP,null);
607                                    convolve.filter(img, tmpimg);
608                                    rate++;
609                                    img = tmpimg;
610                            }
611                    }
612                    return img;
613            }
614    
615    /**
616     *  »þÆÝ È¿°úÁÖ±â
617     * @param  img  ´ë»ó À̹ÌÁö
618     * @param  rate  ÂüÁ¶ºñÀ²
619     * @return  BufferedImage
620     */
621            public BufferedImage effectSharpen(BufferedImage img, int rate){
622                    if (rate == 0) return img;
623                    BufferedImage tmpimg = this.getImg(img.getWidth(),img.getHeight());
624                    Kernel kernel = this.getKernel("S", (float)rate);
625                    ConvolveOp convolve = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP,null);
626                    convolve.filter(img,tmpimg);
627                    img = tmpimg;
628                    rate--;
629                    return this.effectSharpen(img,rate);
630            }
631    
632    /**
633     *  ±×·¹ÀÌ È¿°úÁÖ±â
634     * @param  img  ´ë»ó À̹ÌÁö
635     * @return  BufferedImage
636     */
637            public BufferedImage effectGray(BufferedImage img){
638                    ColorConvertOp colorConvert = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
639                    colorConvert.filter(img, img);
640                    return img;
641            }
642    
643    /**
644     *  ±×·¹ÀÌ È¿°úÁÖ±â
645     * @param  img  ´ë»ó À̹ÌÁö
646     */
647            public void filterGray(BufferedImage img) {
648                    img = this.effectGray(img);
649            }
650            
651    /**
652     *  ³×°¡Æ¼ºê È¿°úÁÖ±â
653     * @param  img  ´ë»ó À̹ÌÁö
654     * @return  BufferedImage
655     */
656            public BufferedImage effectReverse(BufferedImage img){
657                    byte reverse[] = new byte[256];
658                    for (int i = 0; i < 256; i++) 
659                            reverse[i] = (byte) (255 - i);
660                    return this.effectEnd(img, new ByteLookupTable(0, reverse));
661            }
662    
663    /**
664     *  ¹à±âÁ¶Á¤ È¿°úÁÖ±â
665     * @param  img  ´ë»ó À̹ÌÁö
666     * @param  bright  ´ë»ó ¹à±â(±âº» 100, 100 ÀÌÇÏ : ¾îµÓ°Ô, 100 ÀÌ»ó : ¹à°Ô)
667     * @return  BufferedImage
668     */
669            public BufferedImage effectBrighten(BufferedImage img, int bright){
670                    bright = bright - 100;
671                    if (bright == 0)
672                            return img;
673                    short brighten[] = new short[256];
674                    short alpha[] = new short[256];
675                    for (int i = 0; i < 256; i++) {
676                            brighten[i] = (short) this.getSafeColor(i + bright);
677                            alpha[i] = (short) i;
678                    }
679                    short[][] lookup = new short[][]{brighten, brighten, brighten, alpha};
680                    return this.effectEnd(img, new ShortLookupTable(0, lookup));
681            }
682    
683    /**
684     *  ÄÁÆ®¶ó½ºÅÍ È¿°úÁÖ±â
685     * @param  img  ´ë»ó À̹ÌÁö
686     * @param  cont  ´ë»ó ´ëºñ(±âº» 100, 100 ÀÌÇÏ : °­ÇϰÔ, 100 ÀÌ»ó : ¾àÇϰÔ)
687     * @return  BufferedImage
688     */
689            public BufferedImage effectContrast(BufferedImage img, int cont){
690                    short brighten[] = new short[256];
691                    short alpha[] = new short[256];
692                    double cont_rate = 0;
693                    cont_rate =  ((double) (cont - 100) /100) * 0.5;
694                    if (cont_rate == 0) return img;
695                    for (int i = 0; i < 256; i++) {
696                            brighten[i] = (short) this.getSafeColor((int) (i * (cont_rate + 1)));
697                            alpha[i] = (short) i;
698                    }
699                    short[][] lookup = new short[][]{brighten, brighten, brighten, alpha};
700                    return this.effectEnd(img, new ShortLookupTable(0, lookup));
701            }
702    
703    /**
704     *  ¾ÈÀü»ö»ó °¡Á®¿À±â
705     * @param  rgb  ´ë»ó»ö»ó
706     * @return  ¾ÈÀü»ö»ó
707     */
708            public int getSafeColor(int rgb) {
709                    return Math.max(Math.min(rgb, 255), 0);
710            }
711    
712    /**
713     *  µàÅæ È¿°úÁÖ±â
714     * @param  img  ´ë»ó À̹ÌÁö
715     * @param  rplus  Àû»ö ÂüÁ¶°ª(0-255)
716     * @param  gplus  ±×¸° ÂüÁ¶°ª(0-255)
717     * @param  bplus  ºí·ç ÂüÁ¶°ª(0-255)
718     * @return  BufferedImage
719     */
720            public BufferedImage filterDuotone(BufferedImage img, int rplus, int gplus, int bplus) {
721                    byte[] red_table = new byte[256];
722                    byte[] green_table = new byte[256];
723                    byte[] blue_table = new byte[256];
724                    byte[] alpha_table = new byte[256];
725                    for(int i = 0; i < 256; i++) {
726                            red_table[i] = (byte) this.getSafeColor(i + rplus);
727                            green_table[i] = (byte) this.getSafeColor(i + gplus);
728                            blue_table[i] = (byte) this.getSafeColor(i + bplus);
729                            alpha_table[i] = (byte) i;
730                    }
731                    byte[][] lookup = new byte[][]{red_table, green_table, blue_table,alpha_table};
732                    return this.effectEnd(img.getSubimage(0,0, img.getWidth(), img.getHeight()), new ByteLookupTable(0, lookup));
733            }
734    
735    /**
736     *  ³ëÀÌÁî È¿°úÁÖ±â
737     * @param  img  ´ë»ó À̹ÌÁö
738     * @param  noise  ³ëÀÌÁîºñÀ²(1 ÃÖ´ë)
739     */
740            public void filterNoise(BufferedImage img, int noise) {
741                    Random rand = new Random();
742                    for (int x = 0; x < img.getWidth() ; ++x) {
743                            for (int y = 0; y < img.getHeight(); ++y) {
744                                    Color col = new Color(img.getRGB(x,y));
745                                    if (rand.nextInt(noise) == 0) {
746                                            int mod_color = 20 - rand.nextInt(40);
747                                            int red = this.getSafeColor(col.getRed() + mod_color);
748                                            int green = this.getSafeColor(col.getGreen() + mod_color);
749                                            int blue = this.getSafeColor(col.getBlue() + mod_color);
750                                            img.setRGB(x,y,(new Color(red,green,blue)).getRGB());
751                                    } 
752                            }
753                    }
754            }
755    
756    /**
757     *  ÀÜ»óÈ¿°ú È¿°úÁÖ±â
758     * @param  img  ´ë»ó À̹ÌÁö
759     * @param  dist  ÀÜ»ó°Å¸®
760     */
761            public void filterScatter(BufferedImage img, int dist) {
762                    Random rand = new Random();
763                    for (int x = 0; x < img.getWidth() ; ++x) {
764                            for (int y = 0; y < img.getHeight(); ++y) {
765                                    int distx = dist - rand.nextInt(dist * 2);
766                                    int disty = dist - rand.nextInt(dist * 2);
767                                    if (x + distx >= img.getWidth()) continue;
768                                    if (x + distx < 0) continue;
769                                    if (y + disty >= img.getHeight()) continue;
770                                    if (y + disty < 0) continue;
771                                    Color oldcol = new Color(img.getRGB(x,y));
772                                    Color newcol = new Color(img.getRGB(x + distx,y+disty));
773                                    img.setRGB(x,y,newcol.getRGB());
774                                    img.setRGB(x + distx,y+disty,oldcol.getRGB());
775                            }
776                    }
777            }
778    
779    /**
780     *  Çʼ¿·¹ÀÌÆ® È¿°úÁÖ±â
781     * @param  img  ´ë»ó À̹ÌÁö
782     * @param  blocksize  ºí·°Å©±â
783     * @return  BufferedImage
784     */
785            public BufferedImage filterPixelate(BufferedImage img, int blocksize) {
786                    BufferedImage tmpimg = this.getImg(img.getWidth(),img.getHeight());
787                    Graphics2D g = tmpimg.createGraphics();
788                    for (int x = 0; x < img.getWidth() ; x += blocksize) {
789                            for (int y = 0; y < img.getHeight(); y += blocksize) {
790                                    Color col = new Color(img.getRGB(x,y));
791                                    g.setColor(col);
792                                    g.fillRect(x,y,blocksize,blocksize);
793                            }
794                    }
795                    return tmpimg;
796            }
797    
798    /**
799     *  RGB °ªÀ» int ·Î º¯È¯
800     * @param  hexcolor  RGB °ª
801     * @return  Array(Àû»ö, ±×¸°, ºí·ç)
802     */
803            public int[] hex2Int(String hexcolor){
804                    String hex_r = "", hex_g = "", hex_b = "";
805                    switch(hexcolor.length()) {
806                            case 6 :
807                                    hex_r = hexcolor.substring(0,2);        
808                                    hex_g = hexcolor.substring(2,4);        
809                                    hex_b = hexcolor.substring(4,6);        
810                                    break;
811                            case 7 :
812                                    hex_r = hexcolor.substring(1,3);        
813                                    hex_g = hexcolor.substring(3,5);        
814                                    hex_b = hexcolor.substring(5,7);        
815                                    break;
816                            default :
817                                    hex_r = "FF";
818                                    hex_g = "FF";
819                                    hex_b = "FF";
820                                    break;
821                    } 
822                    int[] rgb = {this.hex2Dec(hex_r),this.hex2Dec(hex_g),this.hex2Dec(hex_b)};
823                    return rgb;
824            }
825            
826    /**
827     *  RGB °ªÀ» Color ·Î º¯È¯
828     * @param  hexcolor  RGB °ª
829     * @return  Color
830     */
831            public Color getColor(String hexcolor){
832                    int[] rgb = this.hex2Int(hexcolor);
833                    return new Color(rgb[0], rgb[1],rgb[2]);
834            }
835    
836    /**
837     *  RGB °ª°ú ¾ËÆÄ°ªÀ» Color ·Î º¯È¯
838     * @param  hexcolor  RGB °ª
839     * @param  alpha  ¾ËÆÄ °ª
840     * @return  Color
841     */
842            public Color getColor(String hexcolor, int alpha){
843                    int[] rgb = this.hex2Int(hexcolor);
844                    return new Color(rgb[0], rgb[1],rgb[2], alpha);
845            }
846     
847    /**
848     *  Color ¸¦ ¼ýÀÚ·Î º¯È¯
849     * @param  intcolor ´ë»ó »ö»ó 
850     * @return  »ö»ó¼ýÀÚ
851     */
852        public int color2int(Color intcolor) {
853                    return intcolor.hashCode();
854            }
855       
856    /**
857     *  HEX °ªÀ» 10Áø¼ö·Î º¯È¯
858     * @param  s ´ë»ó hex °ª
859     * @return  10Áø¼ö
860     */
861        public int hex2Dec(String s ) {
862            s = s.toUpperCase();
863            int h1 = "0123456789ABCDEF".indexOf(s.substring(0,1));
864            int h2 = "0123456789ABCDEF".indexOf(s.substring(1,2));
865            return (h1*16)+h2;
866        }
867    
868    /**
869     *  ÁÖ¾îÁø À̹ÌÁö¸¦ ±âº»À̹ÌÁö¿¡ º¹»ç
870     * @param  fileName À̹ÌÁöÆÄÀϸí
871     * @param  x ´ë»ó X ÁÂÇ¥
872     * @param  y ´ë»ó Y ÁÂÇ¥
873     * @param  w ´ë»ó °¡·Î
874     * @param  h ´ë»ó ¼¼·Î
875     */
876            public void copy(String fileName, int x, int y, int w, int h){
877                    BufferedImage img = this.load(fileName);
878                    this.copy(img,x,y,w,h);
879            }
880    
881    /**
882     *  ÁÖ¾îÁø À̹ÌÁö¸¦ ±âº»À̹ÌÁö¿¡ º¹»ç
883     * @param  img º¹»çÇÒ À̹ÌÁö
884     * @param  x ´ë»ó X ÁÂÇ¥
885     * @param  y ´ë»ó Y ÁÂÇ¥
886     * @param  w ´ë»ó °¡·Î
887     * @param  h ´ë»ó ¼¼·Î
888     */
889            public void copy(BufferedImage img, int x, int y, int w, int h){
890                    this.copy(img, x, y, 0,0,w,h);
891            }
892    
893    /**
894     *  ÁÖ¾îÁø À̹ÌÁö¸¦ ±âº»À̹ÌÁö¿¡ º¹»ç
895     * @param  img º¹»çÇÒ À̹ÌÁö
896     * @param  x ´ë»ó X ÁÂÇ¥
897     * @param  y ´ë»ó Y ÁÂÇ¥
898     * @param  w ´ë»ó °¡·Î
899     * @param  h ´ë»ó ¼¼·Î
900     */
901            public void copy(BufferedImage img, int x, int y, int w, int h, int sx , int sy , Boolean smart_copy){
902                    if (w == 0 || h == 0) {
903                            w = img.getWidth();
904                            h = img.getHeight();
905                    }
906                    if (smart_copy) {
907                            int img_w = this.img.getWidth();
908                            int img_h = this.img.getHeight();
909                            if (x + w > img_w) {
910                                    sx += (x + w - img_w);
911                                    w -= (x + w - img_w);
912                            }
913                            if (y + h > img_h) {
914                                    sy += (y + h - img_h);
915                                    h -= (y + h - img_h);
916                            }
917                    }
918                    this.copy(img, x, y, sx, sy, w, h);
919            }
920    
921    /**
922     *  ÁÖ¾îÁø À̹ÌÁö¸¦ ±âº»À̹ÌÁö¿¡ º¹»ç
923     * @param  img º¹»çÇÒ À̹ÌÁö
924     * @param  x ´ë»ó X ÁÂÇ¥
925     * @param  y ´ë»ó Y ÁÂÇ¥
926     */
927            public void copy(BufferedImage img, int x, int y){
928                    int h = img.getHeight();
929                    int w = img.getWidth();
930                    this.copy(img, x, y, 0,0,w, h);
931            }       
932    
933    /**
934     *  ÁÖ¾îÁø À̹ÌÁö¸¦ ±âº»À̹ÌÁö¿¡ º¹»ç
935     * @param  img º¹»çÇÒ À̹ÌÁö
936     * @param  x ´ë»ó X ÁÂÇ¥
937     * @param  y ´ë»ó Y ÁÂÇ¥
938     * @param  sx º¹»çÇÒÀ̹ÌÁöÀÇ X ÁÂÇ¥
939     * @param  sy º¹»çÇÒÀ̹ÌÁöÀÇ Y ÁÂÇ¥
940     * @param  sw º¹»çÇÒÀ̹ÌÁöÀÇ °¡·ÎÅ©±â
941     * @param  sh º¹»çÇÒÀ̹ÌÁöÀÇ ¼¼·ÎÅ©±â
942     */
943            public void copy(BufferedImage img, int x, int y, int sx, int sy, int sw, int sh){
944                    if (sw > 0 & sh > 0) {
945                            if (img.getWidth() >= sx + sw && img.getHeight() >= sy + sh) {
946                                    BufferedImage newimg = img.getSubimage(sx,sy,sw,sh);
947                                    this.getGraphic().drawImage(newimg, x, y, sw, sh, null);
948                            }
949                    }
950            }       
951    
952    
953    /**
954     *  ±âº»À̹ÌÁö¿¡ ¹®ÀÚ³Ö±â
955     * @param  text ³ÖÀ» ¹®ÀÚ
956     * @param  x ´ë»ó X ÁÂÇ¥
957     * @param  y ´ë»ó Y ÁÂÇ¥
958     * @param  hexcolor ±Û¾¾ »ö»ó
959     */
960            public void text(String text, int x, int y, String hexcolor){
961                    Graphics2D g = this.getGraphic();
962                    g.setColor(this.getColor(hexcolor));
963                    g.drawString(text, (float)x, (float)y);
964            }
965    
966    /**
967     *  ±âº»À̹ÌÁö¿¡ ¹®ÀÚ³Ö±â
968     * @param  text ³ÖÀ» ¹®ÀÚ
969     * @param  x ´ë»ó X ÁÂÇ¥
970     * @param  y ´ë»ó Y ÁÂÇ¥
971     */
972            public void text(String text, int x, int y){
973                    this.text(text, x, y, "#464646");
974            }
975    
976    /**
977     *  À̹ÌÁö Å©±âÁ¶Á¤
978     * @param  img ´ë»óÀ̹ÌÁö
979     * @param  w ´ë»ó °¡·ÎÅ©±â
980     * @param  h ´ë»ó ¼¼·ÎÅ©±â
981     * @return  BufferedImage
982     */
983            public BufferedImage resize(BufferedImage img, int w, int h){
984                    BufferedImage target = this.getImg(w,h);
985                    Graphics2D g2 = target.createGraphics();
986                    g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
987                    double scalex = (double) target.getWidth()/ img.getWidth();
988                    double scaley = (double) target.getHeight()/ img.getHeight();
989                    AffineTransform xform = AffineTransform.getScaleInstance(scalex, scaley);
990                    g2.drawRenderedImage(img, xform);
991                    g2.dispose();
992                    return target;
993            }
994    
995    /**
996     *  À̹ÌÁö Å©±âÁ¶Á¤
997     * @param  img ´ë»óÀ̹ÌÁö
998     * @param  w ´ë»ó °¡·ÎÅ©±â
999     * @return  BufferedImage
1000     */
1001            public BufferedImage resize(BufferedImage img, int w){
1002                    int ow = img.getWidth();
1003                    int oh = img.getHeight();
1004                    int h = (int)(oh * (double)((double)w/(double)ow));
1005                    return this.resize(img, w, h);
1006            }       
1007            
1008    /**
1009     *  À̹ÌÁö Å©±âÁ¶Á¤(ÀåÃà ´ë»ó Á¶Á¤)
1010     * @param  img ´ë»óÀ̹ÌÁö
1011     * @param  max_size ÀåÃà ÃÖ´ëÅ©±â
1012     * @return  BufferedImage
1013     */
1014            public BufferedImage resizeMax(BufferedImage img, int max_size){
1015                    int ow = img.getWidth();
1016                    int oh = img.getHeight();
1017                    if (ow > max_size || oh > max_size) {
1018                            double rate = (double)((double)ow/(double)oh);
1019                            if (rate > 1) {
1020                                    ow = max_size;
1021                                    oh = (int)(max_size / rate);
1022                            } else {
1023                                    ow = (int)(max_size * rate);
1024                                    oh = max_size;
1025                            }       
1026                            img = this.resize(img, ow, oh);
1027                    }
1028                    return img;
1029            }       
1030    
1031    /**
1032     *  À̹ÌÁö ¹Ýº¹
1033     * @param  img ´ë»óÀ̹ÌÁö
1034     * @param  w ´ë»ó°¡·ÎÅ©±â
1035     * @param  h ´ë»ó¼¼·ÎÅ©±â
1036     * @return  BufferedImage
1037     */
1038            public BufferedImage fill(BufferedImage img, int w, int h){
1039                    int oh = img.getHeight();
1040                    int ow = img.getWidth();
1041                    BufferedImage newimg = this.getImg(w,h);
1042                    Graphics2D g = newimg.createGraphics();
1043                    int x = 0, y = 0;
1044                    do {
1045                            y = 0;
1046                            do {
1047                                    g.drawImage(img, x, y, ow, oh, null);
1048                                    y = y + oh;
1049                            } while (y <= h + oh);
1050                            x = x + ow;
1051                    } while (x <= w + oh);
1052                    return newimg;
1053            }
1054    
1055    /**
1056     *  À̹ÌÁö¿¡¼­ ƯÁ¤¿µ¿ª°¡Á®¿À±â
1057     * @param  img ´ë»óÀ̹ÌÁö
1058     * @param  pos ´ë»óÀ§Ä¡(1:Áß°£»ó, 2 : ÁÂÁß°£, 3 : ÇÏÁß°£, 4: ÁÂÁß°£,0 : Áß°£Áß°£) 
1059     * @param  w ´ë»ó°¡·ÎÅ©±â
1060     * @param  h ´ë»ó¼¼·ÎÅ©±â
1061     * @return  BufferedImage
1062     */
1063            public BufferedImage getFilled(BufferedImage img, int pos, int w, int h){
1064                    int fw = img.getWidth();
1065                    int fh = img.getHeight();
1066                    BufferedImage newimg = this.getImg(w,h);
1067                    switch(pos) {
1068                            case 1 : 
1069                                    newimg = img.getSubimage(4,0,fw-8,4);
1070                                    break;
1071                            case 2 : 
1072                                    newimg = img.getSubimage(fw-4,4,4,fh-8);
1073                                    break;
1074                            case 3 : 
1075                                    newimg = img.getSubimage(4,fh-4,fw-8,4);
1076                                    break;
1077                            case 4 : 
1078                                    newimg = img.getSubimage(0,4,4,fh-8);
1079                                    break;
1080                            case 0 : 
1081                                    newimg = img.getSubimage(4,4,fw-8,fh-8);
1082                                    break;
1083                    }
1084                    return this.fill(newimg, w,h);          
1085            }
1086    
1087    /**
1088     *  ÇÁ·¹ÀÎ À̹ÌÁö Àоî¿À±â
1089     * @param  frmName ÇÁ·¹ÀÓÀ̸§
1090     * @param  linecolor ¶óÀλö»ó
1091     * @param  bgcolor ¹è°æ»ö»ó
1092     * @return  BufferedImage
1093     */
1094            public BufferedImage loadFrame(String frmName, String linecolor, String bgcolor){
1095                    String compiled_filename = "imgstyle/compiled/" + rainUtil.replace("#", "", bgcolor + "_" + linecolor + "_" + frmName + "_main_java.png").toLowerCase();
1096                    if ((new File(this.getBaseRoot() + compiled_filename)).exists()) {      
1097                            return this.load(compiled_filename);
1098                    } else {
1099                            BufferedImage frmimg = this.load("imgstyle/"+frmName+"_main.png");
1100                            int fw = frmimg.getWidth();
1101                            int fh = frmimg.getHeight();
1102                            BufferedImage newimg = this.getImg(fw,fh);
1103                            int bg = this.getColor(bgcolor).hashCode();
1104                            int line = this.getColor(linecolor).hashCode() ;
1105                            int trance = this.getColor("#464646",0).hashCode();
1106                            String lastColor = "";
1107                            for(int x = 0; x < fw; x++) {
1108                                    for(int y = 0; y < fh; y++) {
1109                                            int pixcolor = frmimg.getRGB(x,y);
1110                                            if (pixcolor == -16777216) 
1111                                                    newimg.setRGB(x,y, line);
1112                                            else if (pixcolor == -16776961)
1113                                                    newimg.setRGB(x,y, trance);
1114                                            else if (pixcolor == -1)
1115                                                    newimg.setRGB(x,y, bg);
1116                                    }
1117                            }
1118                            try {
1119                                    ImageIO.write(newimg, "png", new File(this.getBaseRoot()+ compiled_filename));
1120                            } catch(Exception e) { }
1121                            return newimg;
1122                    }
1123            }
1124            
1125    /**
1126     *  ÇöÀçÀÇ À̹ÌÁö¿¡ ÇÁ·¹ÀÓ ³Ö±â
1127     * @param  frmName ÇÁ·¹ÀÓÀ̸§
1128     * @param  lineColor ¶óÀλö»ó
1129     * @param  bgColor ¹è°æ»ö»ó
1130     */
1131            public void setFrame(String frmName, String lineColor, String bgColor){
1132                    int oh = this.img.getHeight();
1133                    int ow = this.img.getWidth();
1134                    BufferedImage tmpimg;
1135                    BufferedImage frmimg = this.loadFrame(frmName, lineColor, bgColor);
1136                    int fh = frmimg.getHeight();
1137                    int fw = frmimg.getWidth();
1138                    this.copy(frmimg, 0,0, 0,0,4,4);
1139                    this.copy(frmimg, ow-4,0, fw-4,0,4,4);
1140                    this.copy(frmimg, 0,oh-4, 0,fh-4,4,4);
1141                    this.copy(frmimg, ow-4,oh-4, fw-4,fh-4,4,4);
1142                    this.copy(this.getFilled(frmimg,1, ow-8, 4), 4,0);
1143                    this.copy(this.getFilled(frmimg,2, 4, oh-8), ow-4,4);
1144                    this.copy(this.getFilled(frmimg,3, ow-8, 4), 4,oh-4);
1145                    this.copy(this.getFilled(frmimg,4, 4, oh-8), 0,4);
1146                    this.copy(this.getFilled(frmimg,0, ow-8, oh-8), 4,4);
1147            }
1148    
1149    /**
1150     *  ÇöÀçÀÇ À̹ÌÁö¿¡ ÇÁ·¹ÀÓ ³Ö±â
1151     * @param  frmName ÇÁ·¹ÀÓÀ̸§
1152     */
1153            public void setFrame(String frmName){
1154                    this.setFrame(frmName,"#464646","#FFFFFF");
1155            }
1156    
1157            /**
1158             *  À̹ÌÁö ¹Ýº¹ º¹»ç
1159             * @param  img ´ë»óÀ̹ÌÁö
1160             * @param  ox ´ë»ó X ÁÂÇ¥
1161             * @param  oy ´ë»ó Y ÁÂÇ¥
1162             * @param  ow ´ë»ó°¡·ÎÅ©±â
1163             * @param  oh ´ë»ó¼¼·ÎÅ©±â
1164             * @param  sx ¿øº» X ÁÂÇ¥
1165             * @param  sy ¿øº» Y ÁÂÇ¥
1166             * @param  sw ¿øº»°¡·ÎÅ©±â
1167             * @param  sh ¿øº»¼¼·ÎÅ©±â
1168            */
1169            public void fillCopy(BufferedImage img, int ox, int oy, int ow, int oh, int sx, int sy, int sw, int sh, int stretch_mode){
1170                    int tg_width , tg_height , x =0 , y =0 ;
1171                    if (stretch_mode == 0) {
1172                            this.img.createGraphics().drawImage(img.getSubimage(ox,oy,ow,oh), sx, sy, sw, sh, null);
1173                    } else {
1174                            do {
1175                                    y = 0;
1176                                    do {
1177                                            if (y < sh || x < sw) {
1178                                                    tg_width = (x + ow > sw) ? sw - x : ow;
1179                                                    tg_height = (y + oh > sh) ? sh - y : oh;
1180                                                    this.copy(img, sx + x, sy + y, tg_width, tg_height ,ox + (x % ow), oy + (y % oh), false);
1181                                            }                               
1182                                            y += oh;
1183                                    } while(y < sh);
1184                                    x += ow;
1185                            } while(x < sw);
1186                    }
1187            }
1188    
1189            /**
1190             *  ÇÁ·¹ÀÓ Á¤º¸ XML °¡Á®¿À±â
1191            */
1192            public String getSkinXml(){
1193                    if (!rainUtil.file_exists("skin/skin_editorinfo.xml") || 
1194                            Math.round((new File(this.getBaseRoot()+"skin/skin_editorinfo.xml")).lastModified()/(long)1000) < 
1195                            Math.round((new File(this.getBaseRoot()+"skin/skin_masterinfo.ini")).lastModified()/(long)1000)
1196                            ) {
1197                            rainProperties skinmaster = new rainProperties(this.getBaseRoot()+ "skin/skin_masterinfo", true);
1198                            String xml = "";
1199                            BufferedImage bgtable = this.load("skin/1320x1320.png");
1200                            for (Enumeration e = skinmaster.propertyNames() ; e.hasMoreElements() ;) {
1201                                    String skin_key = e.nextElement().toString();
1202                                    String skin_name = "";
1203                                    int skin_seqn = 0;
1204                                    String[] tmp_skinname =skinmaster.get(skin_key).split(" ");
1205                                    if (tmp_skinname.length > 1) {
1206                                            skin_name = tmp_skinname[0];
1207                                            skin_seqn = rainUtil.string2Int(tmp_skinname[1]);
1208                                    }
1209                                    if (skin_seqn > 0) {
1210                                            int skin_no = 0;
1211                                            Vector reg = new Vector();
1212                                            if  (rainUtil.find("s([0-9]+)", skin_key, reg))
1213                                                    skin_no = rainUtil.string2Int(reg.get(1).toString());
1214                                            String fileName = "skin/120x120bg.png_K" + skin_no + ".png";
1215                                            if (this.makeThumb(fileName)) {
1216                                                    String img_name = "skin/icon/" + skin_no +".png";
1217                                                    if (rainUtil.file_exists(img_name))
1218                                                            rainUtil.unlink(img_name);
1219                                                    rainUtil.rename(fileName, img_name);
1220                                                    BufferedImage tmp = this.load(img_name).getSubimage(0,0,120,120);
1221                                            try {
1222                                                            ImageIO.write(tmp, "png", new File(this.getBaseRoot() + "skin/icon/icon_" + skin_no + ".png"));
1223                                                    } catch(Exception ioerr) { }
1224                                                    if (skin_seqn > 0 && skin_seqn < 100) {
1225                                                            int x = (skin_seqn % 10) * 120 + 60;
1226                                                            int y = (int) Math.floor(skin_seqn/10) * 120 + 60;
1227                                                            bgtable.createGraphics().drawImage(tmp, x, y, 110, 110, null);
1228                                                    }
1229                                            }
1230                                            rainProperties skininfo = new rainProperties(this.getBaseRoot() + "skin/" + skin_name, true);
1231                                            xml += "<item>\r\n";
1232                                            xml += "\t<name><![CDATA["+skin_no+"]]></name>\r\n";
1233                                            xml += "\t<seqn><![CDATA["+skin_seqn+"]]></seqn>\r\n";
1234                                            xml += "\t<icon><![CDATA[icon_"+skin_no+".png]]></icon>\r\n";
1235                                            xml += "\t<description><![CDATA["+rainUtil.replace("\"","",skininfo.get("title"))+"]]></description>\r\n";
1236                                            xml += "</item>\r\n";
1237                                    }
1238                            }
1239                    try {
1240                                    ImageIO.write(bgtable, "png", new File(this.getBaseRoot() + "../images/skin_thumbnail.png"));
1241                                    FileWriter fout = new FileWriter(new File(this.getBaseRoot() + "skin/skin_editorinfo.xml"), false);
1242                                    BufferedWriter bout = new BufferedWriter(fout);
1243                                    bout.write(xml);
1244                                    bout.close();
1245                                    fout.close();
1246                            } catch(Exception e) { }
1247                            return xml;
1248                    } else {
1249                            rainFile file = new rainFile(this.getBaseRoot());
1250                            return file.fileLoader("skin/skin_editorinfo.xml");
1251                    }
1252            }
1253    
1254            /**
1255             *  ÇÁ·¹ÀÓ Á¤º¸ °¡Á®¿À±â
1256             * @param  frmName ÇÁ·¹ÀÓ¸í
1257            */
1258            public rainProperties loadSkin(String frmName){
1259                    rainProperties pro = new rainProperties();
1260                    rainProperties skinpro = new rainProperties(this.getBaseRoot() + "skin/skin_masterinfo", true);
1261                    String[] tmpfrmName = skinpro.get("s" + frmName).split(" ");
1262                    frmName = tmpfrmName[0];
1263                    if (!frmName.equals("")) {
1264                            pro = new rainProperties(this.getBaseRoot() + "skin/" + frmName, true);
1265                            String tmp = "";
1266                            String[] prokey = new String[]{"extraspace","upleft", "upmid", "upright", "ctleft", "ctright", "btleft", "btmid", "btright", "pic_drawpt"};
1267                            if (!pro.get("file").equals("")) {
1268                                    pro.setProperty("skinconf", frmName);
1269                                    pro.setProperty("skinimg", frmName + ".png");
1270                                    for(int i = 0; i < prokey.length; i++) {
1271                                            tmp = pro.getProperty(prokey[i]);
1272                                            if (!tmp.equals("")) {
1273                                                    String[] tmpinfo = tmp.split(" ");
1274                                                    if (tmpinfo.length ==2) {
1275                                                            pro.setProperty(prokey[i] +"_0",tmpinfo[0]);
1276                                                            pro.setProperty(prokey[i] +"_1",tmpinfo[1]);
1277                                                    }
1278                                            }
1279                                    }
1280                            }                       
1281                    }
1282                    return pro;
1283            }
1284            /**
1285             *  À̹ÌÁö¿¡ Text Ãß°¡Çϱâ
1286             * @param  src_img ÇÁ·¹ÀÓ¸í
1287             * @param  text °¡·Î¼¼·Î ¿©¹é
1288             * @param  padding °¡·Î¼¼·Î ¿©¹é
1289            */
1290    
1291            public BufferedImage addText(BufferedImage src_img, String[] text, int padding){
1292                    if (text.length > 0) {
1293                            int text_length = 0;
1294                            for(int i =0; i < text.length; i++) 
1295                                    if (!text[i].equals("")) text_length++;
1296                            int add_height = text_length * 15 + padding *2;
1297                            int img_width = src_img.getWidth();
1298                            int img_height = src_img.getHeight() + add_height;
1299                            BufferedImage img = this.getImg(img_width, img_height);
1300                            Graphics2D g = img.createGraphics();
1301                            g.setColor(this.getColor("#FFFFFF"));
1302                            g.fillRect(0,0,img_width,img_height);
1303                            g.setColor(this.getColor("#464646"));
1304                            g.setFont(new Font("Monospaced",Font.BOLD,11));
1305                            int y = src_img.getHeight() + Math.round(padding/2);
1306                            float  base_x = (float) img_width - padding;
1307                            for(int i =0; i < text.length; i++) {
1308                                    text[i] = text[i].trim();
1309                                    if (!text[i].equals("")) 
1310                                            g.drawString(text[i], base_x - (float) (text[i].length()*7) , (float) (y +=15));
1311                            }
1312                            g.drawImage(src_img, 0, 0, src_img.getWidth(), src_img.getHeight(), null);
1313                            src_img = img;
1314                    }
1315                    return src_img;
1316            }
1317    
1318            /**
1319             *  À̹ÌÁö¿¡ ÇÁ·¹ÀÓ Àû¿ëÇϱâ
1320             * @param  img À̹ÌÁö
1321             * @param  frmName ÇÁ·¹ÀÓ¸í
1322            */
1323            public BufferedImage setSkin(BufferedImage img, String frmName){
1324                    rainProperties skininfo = this.loadSkin(frmName);
1325                    int img_width = img.getWidth();
1326                    int img_height = img.getHeight();
1327                    if (skininfo.get("skinimg").equals(""))
1328                            return img;
1329                    BufferedImage frm_img = this.load("skin/"+skininfo.get("skinimg"));
1330                    int frm_width, frm_height;
1331                    float resize_rate = 1.0f;
1332                    BufferedImage original_img = null;
1333                    if (!skininfo.get("type").equals("transparent_fit")) {
1334                            if (img_width + skininfo.getInt("extraspace_0") < frm_img.getWidth() || img_height + skininfo.getInt("extraspace_1") < frm_img.getHeight()) {
1335                                    if ((frm_img.getWidth() - skininfo.getInt("extraspace_0")) > 0 && (frm_img.getHeight() - skininfo.getInt("extraspace_1")) > 0)
1336                                            resize_rate = Math.min(img_width/((float)frm_img.getWidth() - skininfo.getInt("extraspace_0")), img_height/((float)frm_img.getHeight() - skininfo.getInt("extraspace_1")));
1337                                    else
1338                                            resize_rate = 1.0f;
1339                                    if (resize_rate > 0.0f && resize_rate != 1.0f) {
1340                                            original_img = img;
1341                                            img = this.resize(img, (int) (img.getWidth()/resize_rate), (int) (img.getHeight()/resize_rate));
1342                                            img_width = img.getWidth();
1343                                            img_height = img.getHeight();
1344                                    }
1345                            }
1346                    }
1347                    frm_width = img_width + skininfo.getInt("extraspace_0") ;
1348                    frm_height = img_height + skininfo.getInt("extraspace_1");
1349    
1350                    this.img = this.getImg(frm_width, frm_height);
1351    
1352                    int frm_y = 0, frm_x = 0;
1353                    int img_y = 0, img_x = 0;
1354                    if (skininfo.get("type").equals("transparent_fit")) {
1355                            this.copy(img, skininfo.getInt("pic_drawpt_0"),skininfo.getInt("pic_drawpt_1"));
1356                            this.img.createGraphics().drawImage(frm_img, 0, 0, frm_width, frm_height, null);
1357                    } else {
1358                            if (!skininfo.get("type").equals(""))
1359                                    this.copy(img, skininfo.getInt("pic_drawpt_0"),skininfo.getInt("pic_drawpt_1"));
1360    
1361                            if (skininfo.getInt("upleft_0") > 0 && skininfo.getInt("upleft_1") > 0)
1362                                    this.copy(frm_img, img_x, img_y, skininfo.getInt("upleft_0"), skininfo.getInt("upleft_1"), frm_x, frm_y, false);
1363                            frm_x += skininfo.getInt("upleft_0");
1364                            img_x += skininfo.getInt("upleft_0");
1365                            int mid_width = frm_width - skininfo.getInt("upleft_0") - skininfo.getInt("upright_0");
1366                            if (mid_width > 0){
1367                                    if (skininfo.getInt("upmid_0") > 0 && skininfo.getInt("upmid_1") > 0)
1368                                            this.fillCopy(frm_img, frm_x, frm_y, skininfo.getInt("upmid_0"),skininfo.getInt("upmid_1"), img_x, img_y, mid_width, skininfo.getInt("upmid_1"), skininfo.getInt("stretch_mode"));
1369                                    img_x += mid_width;
1370                            }
1371                            frm_x += skininfo.getInt("upmid_0");
1372                            if (skininfo.getInt("upright_0") > 0 && skininfo.getInt("upright_1") > 0)
1373                                    this.copy(frm_img, img_x, img_y, skininfo.getInt("upright_0"), skininfo.getInt("upright_1"), frm_x, frm_y, true);
1374                            frm_y += skininfo.getInt("upleft_1");
1375                            frm_x = 0;
1376                            img_y += skininfo.getInt("upleft_1");
1377                            img_x = 0;
1378                            int mid_height = frm_height - skininfo.getInt("upleft_1") - skininfo.getInt("btleft_1");
1379                            if (mid_height > 0) {
1380                                    if (skininfo.getInt("ctleft_0") > 0 && skininfo.getInt("ctleft_1") > 0)
1381                                            this.fillCopy(frm_img, frm_x, frm_y, skininfo.getInt("ctleft_0"),skininfo.getInt("ctleft_1"), img_x, img_y, skininfo.getInt("ctleft_0"),mid_height, skininfo.getInt("stretch_mode"));
1382                                    frm_x += skininfo.getInt("ctleft_0") + skininfo.getInt("upmid_0") ;
1383                                    img_x += skininfo.getInt("ctleft_0")+ mid_width;
1384                                    if (skininfo.getInt("ctright_0") > 0 && skininfo.getInt("ctright_1") > 0)
1385                                            this.fillCopy(frm_img, frm_x, frm_y, skininfo.getInt("ctright_0"),skininfo.getInt("ctright_1"), img_x, img_y, skininfo.getInt("ctright_0"),mid_height, skininfo.getInt("stretch_mode"));
1386                                    frm_x = 0;
1387                                    img_x = 0;
1388                                    img_y += mid_height;
1389                            }
1390                            frm_y += skininfo.getInt("ctleft_1");
1391                            if (skininfo.getInt("btleft_0") > 0 && skininfo.getInt("btleft_1") > 0)
1392                                    this.copy(frm_img, img_x, img_y, skininfo.getInt("btleft_0"), skininfo.getInt("btleft_1"), frm_x, frm_y, true);
1393                            frm_x += skininfo.getInt("btleft_0");
1394                            img_x += skininfo.getInt("btleft_0");
1395                            mid_width = frm_width - skininfo.getInt("btleft_0") - skininfo.getInt("btright_0");
1396                            if (mid_width > 0){
1397                                    if (skininfo.getInt("btmid_0") > 0 && skininfo.getInt("btmid_1") > 0)
1398                                            this.fillCopy(frm_img, frm_x, frm_y, skininfo.getInt("btmid_0"),skininfo.getInt("btmid_1"), img_x, img_y, mid_width, skininfo.getInt("btmid_1"), skininfo.getInt("stretch_mode"));
1399                                    img_x += mid_width;
1400                            }
1401                            frm_x += skininfo.getInt("btmid_0");
1402                            if (skininfo.getInt("btright_0") > 0 && skininfo.getInt("btright_1") > 0)
1403                                    this.copy(frm_img, img_x, img_y, skininfo.getInt("btright_0"), skininfo.getInt("btright_1"), frm_x, frm_y,true);
1404    
1405                    }               
1406                    if (!skininfo.get("type").equals("transparent_fit")) {
1407                            if (original_img == null)
1408                                    original_img = img; 
1409                            if (resize_rate > 0.0f && resize_rate != 1.0f) 
1410                                    this.img = this.resize(this.img, (int)(this.img.getWidth()*resize_rate), (int) (this.img.getHeight()*resize_rate));
1411                            if (skininfo.get("type").equals(""))
1412                                    this.copy(original_img, (int) (skininfo.getInt("pic_drawpt_0")*resize_rate), (int) (skininfo.getInt("pic_drawpt_1")*resize_rate));
1413                    }
1414                    return this.img;
1415            }
1416    
1417            /**
1418             *  À̹ÌÁö¿¡ ÇÁ·¹ÀÓ Àû¿ëÇϱâ
1419             * @param  frmName ÇÁ·¹ÀÓ¸í
1420            */
1421            public BufferedImage setSkintmp(String frmName){
1422                    rainProperties skininfo = this.loadSkin(frmName);
1423                    BufferedImage img = this.load("skin/120x120bg.png");
1424                    int img_width = 100;
1425                    int img_height = 100;
1426                    if (skininfo.get("skinimg").equals(""))
1427                            return img;
1428                    BufferedImage frm_img = this.load("skin/"+skininfo.get("skinimg"));
1429                    int frm_width, frm_height;
1430                    if (!skininfo.get("type").equals("transparent_fit")) {
1431                            if (img_width + skininfo.getInt("extraspace_0") < frm_img.getWidth() || img_height + skininfo.getInt("extraspace_1") < frm_img.getHeight()) {
1432                                    double resize_rate = Math.min((double)(img_width + skininfo.getInt("extraspace_0")) / (double)frm_img.getWidth()/1.2f, (double)(img_height + skininfo.getInt("extraspace_1")) / (float)frm_img.getHeight()/1.2f);
1433                                    String tmp = "", html = "";
1434                                    String[] prokey = new String[]{"extraspace","upleft", "upmid", "upright", "ctleft", "ctright", "btleft", "btmid", "btright", "pic_drawpt"};
1435                                    for(int i = 0; i < prokey.length; i++) {
1436                                            skininfo.setProperty(prokey[i] +"_0",(int)Math.ceil((double) skininfo.getInt(prokey[i] +"_0") * resize_rate) +"");
1437                                            skininfo.setProperty(prokey[i] +"_1",(int)Math.ceil((double) skininfo.getInt(prokey[i] +"_1") * resize_rate) +"");
1438                                    }
1439                                    frm_width = skininfo.getInt("upleft_0") + skininfo.getInt("upmid_0") + skininfo.getInt("upright_0");
1440                                    frm_height = skininfo.getInt("upleft_1") + skininfo.getInt("ctleft_1") + skininfo.getInt("btleft_1");
1441                                    if (frm_width == 0)
1442                                            frm_width = 1;  
1443                                    if (frm_height == 0)
1444                                            frm_height = 1; 
1445                                    BufferedImage tmp_img = this.getImg(frm_width, frm_height);
1446                                    tmp_img.createGraphics().drawImage(frm_img, 0, 0, frm_width, frm_height, null);
1447                                    frm_img = tmp_img;
1448                            }
1449                    }
1450                    img_width = 120 - skininfo.getInt("extraspace_0");
1451                    img_height = 120 - skininfo.getInt("extraspace_1");
1452                    if (img_width <= 0)
1453                            img_width = 1;  
1454                    if (img_height <= 0)
1455                            img_height = 1; 
1456    
1457                    img = img.getSubimage(0,0, img_width, img_height);
1458                    frm_width = 120;
1459                    frm_height = 120;
1460                    this.img = this.load("skin/120x120.png");;
1461                    if (!skininfo.get("type").equals("")) {
1462                            Graphics2D g = this.img.createGraphics();
1463                            g.setColor(this.getColor("#f0f0f0"));
1464                            g.fillRect(skininfo.getInt("pic_drawpt_0"),skininfo.getInt("pic_drawpt_1"),img_width,img_height);
1465                    }
1466                    int frm_y = 0, frm_x = 0;
1467                    int img_y = 0, img_x = 0;
1468                    if (skininfo.get("type").equals("transparent_fit")) {
1469                            this.img.createGraphics().drawImage(frm_img, 0, 0, frm_width, frm_height, null);
1470                    } else {
1471                            if (skininfo.getInt("upleft_0") > 0 && skininfo.getInt("upleft_1") > 0)
1472                                    this.copy(frm_img, img_x, img_y, skininfo.getInt("upleft_0"), skininfo.getInt("upleft_1"), frm_x, frm_y, false);
1473                            frm_x += skininfo.getInt("upleft_0");
1474                            img_x += skininfo.getInt("upleft_0");
1475                            int mid_width = frm_width - skininfo.getInt("upleft_0") - skininfo.getInt("upright_0");
1476                            if (mid_width > 0){
1477                                    if (skininfo.getInt("upmid_0") > 0 && skininfo.getInt("upmid_1") > 0)
1478                                            this.fillCopy(frm_img, frm_x, frm_y, skininfo.getInt("upmid_0"),skininfo.getInt("upmid_1"), img_x, img_y, mid_width, skininfo.getInt("upmid_1"), skininfo.getInt("stretch_mode"));
1479                                    img_x += mid_width;
1480                            }
1481                            frm_x += skininfo.getInt("upmid_0");
1482                            if (skininfo.getInt("upright_0") > 0 && skininfo.getInt("upright_1") > 0)
1483                                    this.copy(frm_img, img_x, img_y, skininfo.getInt("upright_0"), skininfo.getInt("upright_1"), frm_x, frm_y, true);
1484                            frm_y += skininfo.getInt("upleft_1");
1485                            frm_x = 0;
1486                            img_y += skininfo.getInt("upleft_1");
1487                            img_x = 0;
1488                            int mid_height = frm_height - skininfo.getInt("upleft_1") - skininfo.getInt("btleft_1");
1489                            if (mid_height > 0) {
1490                                    if (skininfo.getInt("ctleft_0") > 0 && skininfo.getInt("ctleft_1") > 0)
1491                                            this.fillCopy(frm_img, frm_x, frm_y, skininfo.getInt("ctleft_0"),skininfo.getInt("ctleft_1"), img_x, img_y, skininfo.getInt("ctleft_0"),mid_height, skininfo.getInt("stretch_mode"));
1492                                    frm_x += skininfo.getInt("ctleft_0") + skininfo.getInt("upmid_0") ;
1493                                    img_x += skininfo.getInt("ctleft_0")+ mid_width;
1494                                    if (skininfo.getInt("ctright_0") > 0 && skininfo.getInt("ctright_1") > 0)
1495                                            this.fillCopy(frm_img, frm_x, frm_y, skininfo.getInt("ctright_0"),skininfo.getInt("ctright_1"), img_x, img_y, skininfo.getInt("ctright_0"),mid_height, skininfo.getInt("stretch_mode"));
1496                                    frm_x = 0;
1497                                    img_x = 0;
1498                                    img_y += mid_height;
1499                            }
1500                            frm_y += skininfo.getInt("ctleft_1");
1501                            if (skininfo.getInt("btleft_0") > 0 && skininfo.getInt("btleft_1") > 0)
1502                                    this.copy(frm_img, img_x, img_y, skininfo.getInt("btleft_0"), skininfo.getInt("btleft_1"), frm_x, frm_y, true);
1503                            frm_x += skininfo.getInt("btleft_0");
1504                            img_x += skininfo.getInt("btleft_0");
1505                            mid_width = frm_width - skininfo.getInt("btleft_0") - skininfo.getInt("btright_0");
1506                            if (mid_width > 0){
1507                                    if (skininfo.getInt("btmid_0") > 0 && skininfo.getInt("btmid_1") > 0)
1508                                            this.fillCopy(frm_img, frm_x, frm_y, skininfo.getInt("btmid_0"),skininfo.getInt("btmid_1"), img_x, img_y, mid_width, skininfo.getInt("btmid_1"), skininfo.getInt("stretch_mode"));
1509                                    img_x += mid_width;
1510                            }
1511                            frm_x += skininfo.getInt("btmid_0");
1512                            if (skininfo.getInt("btright_0") > 0 && skininfo.getInt("btright_1") > 0)
1513                                    this.copy(frm_img, img_x, img_y, skininfo.getInt("btright_0"), skininfo.getInt("btright_1"), frm_x, frm_y,true);
1514    
1515                    }               
1516                    if (skininfo.get("type").equals("")) {
1517                            Graphics2D g = this.img.createGraphics();
1518                            g.setColor(this.getColor("#f0f0f0"));
1519                            g.fillRect(skininfo.getInt("pic_drawpt_0"),skininfo.getInt("pic_drawpt_1"),img_width,img_height);
1520                    }
1521                    return this.img;
1522            }
1523    
1524    /**
1525     *  ÇöÀçÀÇ À̹ÌÁö¿¡ À̹ÌÁö ³Ö±â
1526     * @param  imgName À̹ÌÁöÀ̸§
1527     * @param  padding °¡·Î¼¼·Î ¿©¹é
1528     */
1529            public void setImg(String imgName, int padding){
1530                    BufferedImage img = this.load(imgName);
1531                    this.setImg(img, padding);
1532            }
1533    
1534    /**
1535     *  ÇöÀçÀÇ À̹ÌÁö¿¡ À̹ÌÁö ³Ö±â
1536     * @param  img ´ë»óÀ̹ÌÁö
1537     * @param  padding °¡·Î¼¼·Î ¿©¹é
1538     */
1539            public void setImg(BufferedImage img, int padding){
1540                    int ow = this.img.getWidth() - padding *2;
1541                    img = this.resize(img, ow);
1542                    this.text_y = img.getHeight() + (int) ((double) padding * 2 + 5);
1543                    this.text_x = padding;
1544                    this.copy(img, padding, padding);
1545            }
1546    
1547    /**
1548     *  ÇöÀçÀÇ À̹ÌÁö¿¡ ¹®ÀÚ ³Ö±â
1549     * @param  text ¹®ÀÚ
1550     * @param  hexcolor ¹®ÀÚ »ö»ó
1551     */
1552            public void setText(String text, String hexcolor){
1553                    this.text(text, this.text_x, this.text_y, hexcolor);
1554                    this.text_y += 17;
1555            }
1556    
1557    /**
1558     *  ÁÖ¾îÁø À̹ÌÁö ȸÀü
1559     * @param  img ´ë»ó À̹ÌÁö
1560     * @param  degree ȸÀü°¢µµ(1: 90µµ, 2: 180µµ, 3: 270µµ, 0 :ȸÀü¾øÀ½)
1561     * @return  BufferedImage
1562     */
1563            public BufferedImage setRotate(BufferedImage img, double degree){
1564                    if (degree % 4 == 0)
1565                            return img;
1566                    if (img.getWidth() > 1024)
1567                            img = this.resize(img, 1024);
1568                    double angle = Math.toRadians((degree % 4)*90);
1569                    double sin = Math.abs(Math.sin(angle)), cos = Math.abs(Math.cos(angle));
1570                    int w = img.getWidth(), h = img.getHeight();
1571                    int neww = (int)Math.round(w*cos+h*sin), newh = (int)Math.round(h*cos+w*sin);
1572                    BufferedImage result = this.getImg(neww, newh);
1573                    Graphics2D g = result.createGraphics();
1574                    g.translate(((double)neww-(double)w)/2, ((double)newh-(double)h)/2);
1575                    g.rotate(angle, (double)w/2, (double)h/2);
1576                    g.drawRenderedImage(img, null);
1577                    g.dispose();
1578                    return result;
1579            }       
1580            
1581    /**
1582     *  À̹ÌÁö¿¡ ÇÁ·¹ÀÓÃß°¡Çϱâ
1583     * @param  file_name À̹ÌÁöÆÄÀϸí
1584     * @param  img_style ÇÁ·¹ÀÓ¸í
1585     * @param  max_width ÃÖ´ëÆø
1586     * @param  auto_rotate ÀÚµ¿È¸Àü¿©ºÎ
1587     * @param  bgcolor ¹è°æ»ö»ó
1588     * @param  linecolor ¶óÀλö»ó
1589     * @param  fontcolor ±Û¾¾»ö»ó
1590     * @param  sign À̹ÌÁö½ÎÀÎ
1591     * @param  add_picinfo »çÁøÃÔ¿µÁ¤º¸ ³Ö±â¿©ºÎ
1592     * @param  padding_value ÇÁ·¹ÀÓ ¿©¹é
1593     */
1594            public void makeFrame(String file_name, String img_style, int max_width, Boolean auto_rotate, String bgcolor, String linecolor, String fontcolor, String sign  , Boolean add_picinfo, int padding_value) {
1595                    BufferedImage img = this.load(file_name);
1596                    int addheight = 0;
1597                    String photo_info = "";
1598                    String photo_model = "";
1599                    if (add_picinfo || auto_rotate) {
1600                            rainExif exif = new rainExif(file_name);
1601                            photo_model = exif.getModel();
1602                            if (!photo_model.equals("")) {
1603                                    photo_info = exif.getInfo();
1604                                    addheight += 30;
1605                            }
1606                            if (auto_rotate) 
1607                                    img = this.setRotate(img, exif.getRotate());
1608                    }
1609                    if (!sign.equals("")) 
1610                            addheight += 15;
1611                    if (img.getWidth() > max_width)
1612                            img = this.resize(img, max_width);
1613                    int frmWidth = img.getWidth() + padding_value *2;
1614                    int frmHeight = img.getHeight() + padding_value *2 + addheight;
1615                    this.img = this.getImg(frmWidth, frmHeight);
1616                    this.setFrame(img_style);
1617                    this.setImg(img, padding_value);
1618                    if (!sign.equals("")) 
1619                            this.setText(sign, fontcolor);
1620                    if (!photo_model.equals("")) 
1621                            this.setText(photo_model, fontcolor);
1622                    if (!photo_info.equals("")) 
1623                            this.setText(photo_info, fontcolor);
1624                    this.save(file_name);
1625            }
1626    
1627    /**
1628     *  ÆÄÀÏ¸í¿¡¼­ È®ÀåÀÚ °¡Á®¿À±â
1629     * @param  fileName ´ë»óÆÄÀϸí
1630     * @return  ÆÄÀÏÈ®ÀåÀÚ
1631     */
1632            public String name2Ext(String fileName) {
1633                    String tar_file_extension = "";
1634                    if (!fileName.equals("")) {
1635                            tar_file_extension = fileName.substring(fileName.lastIndexOf(".") +1, fileName.length()).toLowerCase();
1636                            if(tar_file_extension.equals("")) tar_file_extension = "tmp";
1637                    }
1638                    return tar_file_extension;
1639            }
1640    
1641    /**
1642     *  ÆÄÀÏ¸í¿¡¼­ È®ÀåÀÚ °¡Á®¿À±â(ÀÚ¹Ù ¾ÈÀüÈ®ÀåÀÚ) - ÀÚ¹Ù¿¡¼­´Â gif À̹ÌÁö »ç¿ëºÒ°¡
1643     * @param  fileName ´ë»óÆÄÀϸí
1644     * @return  ÆÄÀÏÈ®ÀåÀÚ
1645     */
1646            public String name2Ext(String fileName, Boolean java_img) {
1647                    String ext = this.name2Ext(fileName);
1648                    if (ext.equals("gif") && java_img)
1649                            ext = "png";
1650                    return ext;
1651            }
1652            
1653    /**
1654     *  ÇöÀçÀÇ À̹ÌÁö¸¦ ÁÖ¾îÁø ÆÄÀϸíÀ¸·Î ÀúÀå
1655     * @param  fileName ´ë»óÆÄÀϸí
1656     * @return  ¼º°ø¿©ºÎ
1657     */
1658            public boolean save(String fileName) {
1659                    return this.save(fileName, "png");
1660            }       
1661    
1662    /**
1663     *  ÇöÀçÀÇ À̹ÌÁö¸¦ ÁÖ¾îÁø ÆÄÀϸíÀ¸·Î ÀúÀå
1664     * @param  fileName ´ë»óÆÄÀϸí
1665     * @return  ¼º°ø¿©ºÎ
1666     */
1667            public boolean save(String fileName, String fileType) {
1668            try {
1669                    if (rainUtil.checkDir(this.getBaseRoot(), fileName)) {
1670                            String fileext = (fileType.equals(""))?this.name2Ext(fileName, true):fileType;
1671                            if (fileext.equals("jpg")) {
1672                                            Iterator iter = ImageIO.getImageWritersByFormatName("JPG");
1673                                            if (iter.hasNext()) {
1674                                                    ImageWriter writer = (ImageWriter)iter.next();
1675                                                    ImageWriteParam iwp = writer.getDefaultWriteParam();
1676                                                    iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
1677                                                    iwp.setCompressionQuality(0.75f);
1678                                                    FileImageOutputStream output = new FileImageOutputStream(new File(this.getBaseRoot() + fileName));
1679                                                    writer.setOutput(output);
1680                                                    BufferedImage img = new BufferedImage(this.img.getWidth(),this.img.getHeight(),BufferedImage.TYPE_INT_RGB);
1681                                                    img.createGraphics().drawImage(this.img, 0, 0, this.img.getWidth(), this.img.getHeight(), null);
1682                                                    IIOImage image =        new IIOImage(img, null, null);
1683                                                    writer.write(null, image, iwp);
1684                                                    output.close();
1685                                                    return true;
1686                                            } else
1687                                                    return false;
1688                                    } else {
1689                                            ImageIO.write(this.img, fileext, new File(this.getBaseRoot() + fileName));
1690                                            return true;
1691                                    }
1692                            } else
1693                                    return false;
1694            } catch(Exception e) {
1695                            return false;
1696            }
1697            }
1698    
1699    /**
1700     *  ÁÖ¾îÁø À̹ÌÁö¸¦ À¥ºê¶ó¿ìÀú·Î Àü¼Û
1701     * @param  img ´ë»óÀ̹ÌÁö
1702     * @param  response HttpServletResponse
1703     */
1704            public void show(BufferedImage img, HttpServletResponse response) {
1705                    this.show(img, response, "png");
1706            }
1707    
1708    /**
1709     *  ÁÖ¾îÁø À̹ÌÁö¸¦ À¥ºê¶ó¿ìÀú·Î Àü¼Û
1710     * @param  img ´ë»óÀ̹ÌÁö
1711     * @param  response HttpServletResponse
1712     */
1713            public void show(BufferedImage img, HttpServletResponse response, String imgType) {
1714            try {
1715                    if (imgType.equals("jpg")) {
1716                                    BufferedImage nimg = new BufferedImage(img.getWidth(), img.getHeight(),BufferedImage.TYPE_INT_RGB);
1717                                    nimg.createGraphics().drawImage(img, 0, 0, img.getWidth(), img.getHeight(), null);
1718                                    ImageIO.write(nimg, imgType, response.getOutputStream());
1719                            }  else 
1720                                    ImageIO.write(img, imgType, response.getOutputStream());
1721                            response.getOutputStream().flush();
1722                            response.getOutputStream().close();
1723                } catch(Exception e) {}
1724            }       
1725    
1726    /**
1727     *  ÁÖ¾îÁø À̹ÌÁö¸¦ À¥ºê¶ó¿ìÀú·Î Àü¼Û
1728     * @param  imgName ´ë»óÀ̹ÌÁö¸í
1729     * @param  response HttpServletResponse
1730     */
1731            public void show(String imgName, HttpServletResponse response) {
1732                    BufferedImage img = this.load(imgName);
1733                    this.show(img, response, this.name2Ext(imgName, true));
1734            }
1735    }