001/*
002 * Copyright (c) 2009 The openGion Project.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
013 * either express or implied. See the License for the specific language
014 * governing permissions and limitations under the License.
015 */
016package org.opengion.hayabusa.servlet;
017
018import java.awt.Color;
019import java.awt.Font;
020import java.awt.Graphics2D;
021import java.awt.image.BufferedImage;
022import java.io.File;
023import java.io.IOException;
024import java.util.Iterator;
025import javax.imageio.ImageIO;
026import javax.imageio.ImageWriter;
027import javax.imageio.stream.ImageOutputStream;
028
029import jakarta.servlet.ServletException;
030import jakarta.servlet.ServletConfig;
031import jakarta.servlet.http.HttpServlet;
032import jakarta.servlet.http.HttpServletRequest;
033import jakarta.servlet.http.HttpServletResponse;
034import jakarta.servlet.ServletOutputStream;
035
036import jakarta.servlet.annotation.WebInitParam;                                 // 7.3.0.0 (2021/01/06)
037import jakarta.servlet.annotation.WebServlet;                                           // 7.3.0.0 (2021/01/06)
038
039import org.opengion.fukurou.system.Closer ;
040
041/**
042 * 画像イメージに、文字列を動的に合成作成する、サーブレットです。
043 *
044 * 画像イメージを読取り、そこに、引数のテキスト文字列を合成します。
045 * 元は、googleMap のマーカーに、マーカー番号を合成する為に作られました。
046 *
047 * 一般的なサーブレットと同様に、デプロイメント・ディスクリプタ WEB-INF/web.xml に、
048 * servlet 要素と そのマッピング(servlet-mapping)を定義する必要があります。
049 *
050 *     <servlet>
051 *         <servlet-name>makeImage</servlet-name>
052 *         <servlet-class>org.opengion.hayabusa.servlet.MakeImage</servlet-class>
053 *     </servlet>
054 *
055 *     <servlet-mapping>
056 *         <servlet-name>makeImage</servlet-name>
057 *         <url-pattern>/jsp/makeImage</url-pattern>
058 *     </servlet-mapping>
059 *
060 * 一般には、http://サーバー:ポート/システムID/jsp/makeImage?text=番号
061 * 形式のURL でアクセスします。
062 *
063 * @og.rev 3.8.1.1 (2005/11/21) 新規追加
064 * @og.group その他機能
065 *
066 * @version  0.9.0  2000/10/17
067 * @author   Kazuhiko Hasegawa
068 * @since    JDK1.1,
069 */
070@WebServlet(
071        urlPatterns = "/jsp/makeImage" ,
072        initParams  = {
073                @WebInitParam(name="imageFile", value="C:/opengion/uap/webapps/gf/jsp/GF7010/mark.png")
074        }
075)
076public class MakeImage extends HttpServlet {
077        private static final long serialVersionUID = 400020050131L ;
078
079        private static final String FORM_NAME = "png" ; // jpg,BMP,bmp,JPG,wbmp,jpeg,png,PNG,JPEG,WBMP,GIF,gif
080        /** マーカーの基本となるイメージファイル名 */
081        private String imageFile        ;
082
083        /**
084         * デフォルトコンストラクター
085         *
086         * @og.rev 8.5.3.2 (2023/10/13) JDK21対応。警告: デフォルトのコンストラクタの使用で、コメントが指定されていません
087         */
088        public MakeImage() { super(); }         // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
089
090        /**
091         * Servlet の 初期値設定を行います。
092         *
093         * WEB-INF/web.xml ファイルで、<servlet> タグ内で初期値設定を行います。
094         * <init-param>
095         *     <param-name>imageFile</param-name>
096         *     <param-value>G:/webapps/gf/jsp/GF7010/mark.png</param-value>
097         * </init-param>
098         *
099         * @param       config  ServletConfigオブジェクト
100         */
101        @Override
102        public void init( final ServletConfig config ) throws ServletException {
103                super.init( config );
104
105                imageFile = config.getInitParameter("imageFile");
106        }
107
108        /**
109         * GET メソッドが呼ばれたときに実行します。
110         *
111         * 処理は、doPost へ振りなおしています。
112         *
113         * @param       request HttpServletRequestオブジェクト
114         * @param       response        HttpServletResponseオブジェクト
115         *
116         * @og.rev 3.8.1.2 (2005/12/19) 半角カナ-全角カナ変換機能の追加
117         *
118         * @throws ServletException サーブレット関係のエラーが発生した場合、throw されます。
119         * @throws IOException 入出力エラーが発生したとき
120         */
121        @Override
122        public void doGet( final HttpServletRequest request, final HttpServletResponse response )
123                                                        throws ServletException, IOException {
124                doPost( request,response );
125        }
126
127        /**
128         * POST メソッドが呼ばれたときに実行します。
129         *
130         * @param       request HttpServletRequestオブジェクト
131         * @param       response        HttpServletResponseオブジェクト
132         *
133         * @throws ServletException サーブレット関係のエラーが発生した場合、throw されます。
134         * @throws IOException 入出力エラーが発生したとき
135         */
136        @Override
137        public void doPost( final HttpServletRequest request, final HttpServletResponse response )
138                                                        throws ServletException, IOException {
139
140                final String text = request.getParameter( "text" );
141
142                // contentTypeを出力
143                response.setContentType( "image/" + FORM_NAME );
144
145                ServletOutputStream out = null;
146                try {
147                        out = response.getOutputStream();
148                        final BufferedImage img = createImage( text );
149        //              JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
150        //              encoder.encode( img );
151        //              out.flush();
152
153                        final Iterator<ImageWriter> ite = ImageIO.getImageWritersByFormatName( FORM_NAME );     // 4.3.3.6 (2008/11/15) Generics警告対応
154                        final ImageWriter writer = ite.next();                                                                                          // 4.3.3.6 (2008/11/15) Generics警告対応
155                        final ImageOutputStream ios = ImageIO.createImageOutputStream( out );
156                        writer.setOutput( ios );
157                        writer.write( img );
158                        out.flush();
159                        ios.close();
160
161        //              ImageIO.write( img,FORM_NAME,new File( "G:/webapps/gf/jsp/GF7010/test" + FORM_NAME ) );
162                }
163                finally {
164                        Closer.ioClose( out );          // 4.0.0 (2006/01/31) close 処理時の IOException を無視
165                }
166        }
167
168        /**
169         * イメージの合成処理を行います。
170         *
171         * @param       text    合成するテキスト
172         *
173         * @return      イメージの合成されたBufferedImageオブジェクト
174         * @throws IOException 入出力エラーが発生したとき
175         */
176        private BufferedImage createImage( final String text ) throws IOException {
177                // イメージの作成
178        //      BufferedImage image = new BufferedImage(25, 25, BufferedImage.TYPE_INT_ARGB);
179
180                final BufferedImage image = ImageIO.read( new File( imageFile ) );
181                final Graphics2D gph = (Graphics2D)image.getGraphics();
182
183                final int xsp = (text.length() == 1) ? 8 : 2 ;
184
185        //      gph.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
186        //                                               RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
187        //      gph.setColor(new Color(255,255,255));
188        //      gph.fillRect(0,0,25,25);
189                gph.setFont(new Font("Serif", Font.BOLD, 14));
190                gph.setColor(new Color(0,0,255));
191                gph.drawString(text, xsp, 15);
192        //      gph.setColor(new Color(0,255,0));
193        //      gph.drawOval(2,2,22,22);
194
195                gph.dispose();
196
197                return image;
198        }
199
200        /**
201         * PNGイメージの透過色指定を行います。
202         *
203         * 引数のファイル(PNG)を読取り、白色を透過色に変換後、セーブします。
204         * ただし、PNG形式で透過をサポートしているのは、IE7,Firefox,opera 等で、
205         * IE6 は未サポート(グレーになる)です。
206         *
207         * Usage: java org.opengion.hayabusa.servlet.MakeImage IN_FILE OUT_FILE
208         *
209         * @param       args    コマンド引数配列
210         * @throws IOException 入出力エラーが発生したとき
211         */
212        public static void main( final String[] args ) throws IOException {
213
214                final BufferedImage org = ImageIO.read( new File( args[0] ) );
215
216                final int wd = org.getWidth();
217                final int ht = org.getHeight();
218                final BufferedImage dst = new BufferedImage(wd, ht, BufferedImage.TYPE_INT_ARGB);
219                for( int y=0; y<ht; y++ ) {
220                        for( int x=0; x<wd; x++ ) {
221                                if( org.getRGB(x, y) == 0xFFFFFFFF ) {  //白
222                                        dst.setRGB(x, y, 0);    //透明
223                                }
224                                else {
225                                        dst.setRGB(x, y, org.getRGB(x, y));
226                                }
227                        }
228                }
229                ImageIO.write( dst,"png",new File( args[1] ) );
230        }
231}