    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.fukurou.util;
    017
    018import org.opengion.fukurou.system.OgRuntimeException;                          // 6.4.2.0 (2016/01/29)
    019import java.awt.Component;
    020//import java.awt.Graphics;                                                                                     // 8.4.1.0 (2023/02/10) Delete
    021import java.awt.image.BufferedImage;
    022import java.io.File;
    023import java.io.IOException;
    024import javax.imageio.ImageIO;
    025//import java.nio.charset.Charset;                                                                      // 7.2.3.0 (2020/04/10) 8.4.1.0 (2023/02/10) Delete
    026//import java.nio.charset.StandardCharsets;                                                     // 7.2.3.0 (2020/04/10) 8.4.1.0 (2023/02/10) Delete
    027
    028import java.util.HashMap;                                                                                       // 8.4.1.0 (2023/02/10) Add
    029import java.util.Map;                                                                                           // 8.4.1.0 (2023/02/10) Add
    030
    031//import com.swetake.util.Qrcode;                                                                       // 8.4.1.0 (2023/02/10) Delete
    032import com.google.zxing.BarcodeFormat;                                                          // 8.4.1.0 (2023/02/10) Add
    033import com.google.zxing.EncodeHintType;                                                         // 8.4.1.0 (2023/02/10) Add
    034import com.google.zxing.WriterException;                                                        // 8.4.1.0 (2023/02/10) Add
    035import com.google.zxing.client.j2se.MatrixToImageWriter;                        // 8.4.1.0 (2023/02/10) Add
    036import com.google.zxing.common.BitMatrix;                                                       // 8.4.1.0 (2023/02/10) Add
    037import com.google.zxing.qrcode.QRCodeWriter;                                            // 8.4.1.0 (2023/02/10) Add
    038
    039import org.opengion.fukurou.system.HybsConst;                                           // fukurou.util.StringUtil → fukurou.system.HybsConst に変更
    040//import org.opengion.fukurou.system.LogWriter;                                         // 6.4.2.0 (2016/01/29) package変更 fukurou.util → fukurou.system 8.4.1.0 (2023/02/10) Delete
    041
    042/**
    043 * QrcodeImage は、2次元ﾊﾞｰｺｰﾄﾞの QRｺｰﾄﾞｲﾒｰｼﾞを生成する
    044 * 独立したｺﾝﾎﾟｰﾈﾝﾄです。
    045 *
    046 * 8.4.1.0 (2023/02/10) swetake から ZXing への置換
    047 * <del>ここでの使い方は、初期化時に、ｴﾝｺｰﾄﾞする文字列(120Byte以内)と、
    048 * 出力ﾌｧｲﾙ名を指定して、Graphics に描画したQRｺｰﾄﾞｲﾒｰｼﾞを
    049 * JPEG 変換し、指定のﾌｧｲﾙに上書き保存しています。
    050 * QRｺｰﾄﾞ作成に、http://www.swetake.com/ の Qrcode ｸﾗｽを使用しています。
    051 * これが、2004/11/7  ver.0.50beta9 とのことなので、動作ﾁｪｯｸ、および、
    052 * 製品としての保証という意味では、まだ使えるﾚﾍﾞﾙではありませんが、
    053 * ｺｰﾄﾞ計算さえﾊﾞｸﾞっていなければ使えうる為、試験的導入致します。</del>
    054 *
    055 * ZXing (com.google.zxing) の Qrcode ｸﾗｽを使用しています。
    056 * ｴﾝｺｰﾄﾞﾓｰﾄﾞ ('N':数字ﾓｰﾄﾞ 'A':英数字ﾓｰﾄﾞ 'B':8bit byteﾓｰﾄﾞ) は
    057 * 自動判定になる為、廃止されました。
    058 *
    059 * @og.rev 8.4.1.0 (2023/02/10) QRｺｰﾄﾞを swetake から ZXing への置換(encodeMode廃止)
    060 *
    061 * @version     4.0
    062 * @author      Kazuhiko Hasegawa
    063 * @since       JDK5.0,
    064 */
    065public class QrcodeImage extends Component {
    066        /** このプログラムのVERSION文字列を設定します。   {@value} */
    067        private static final String VERSION = "8.4.1.0 (2023/02/10)" ;
    068        private static final long serialVersionUID = 841020230210L ;
    069
    070        // version  0 ～ 39 => 1 ～ 40
    071//      // errCo    H,M    0:H 1:M
    072        // errCo    L,M,Q,H                                             // 7.2.1.0 (2020/03/13)
    073//      // encMd    N,A,B  0:N 1:A 2:B                  // 8.4.1.0 (2023/02/10) Delete
    074
    075        // 8.4.1.0 (2023/02/10) Delete
    076//      private static final int[][][] QC_DATA = new int[][][] {
    077//              {{   17 ,   10 ,   4 } , {   34 ,   20 ,    8 }} ,
    078//              {{   34 ,   20 ,   8 } , {   63 ,   38 ,   16 }} ,
    079//              {{   58 ,   35 ,  15 } , {  101 ,   61 ,   26 }} ,
    080//              {{   82 ,   50 ,  21 } , {  149 ,   90 ,   38 }} ,
    081//              {{  106 ,   64 ,  27 } , {  202 ,  122 ,   52 }} ,
    082//              {{  139 ,   84 ,  36 } , {  255 ,  154 ,   65 }} ,
    083//              {{  154 ,   93 ,  39 } , {  293 ,  178 ,   75 }} ,
    084//              {{  202 ,  122 ,  52 } , {  365 ,  221 ,   93 }} ,
    085//              {{  235 ,  143 ,  60 } , {  432 ,  262 ,  111 }} ,
    086//              {{  288 ,  174 ,  74 } , {  513 ,  311 ,  131 }} ,
    087//              {{  331 ,  200 ,  85 } , {  604 ,  366 ,  155 }} ,
    088//              {{  374 ,  227 ,  96 } , {  691 ,  419 ,  177 }} ,
    089//              {{  427 ,  259 , 109 } , {  796 ,  483 ,  204 }} ,
    090//              {{  468 ,  283 , 120 } , {  871 ,  528 ,  223 }} ,
    091//              {{  530 ,  321 , 136 } , {  991 ,  600 ,  254 }} ,
    092//              {{  602 ,  365 , 154 } , { 1082 ,  656 ,  277 }} ,
    093//              {{  674 ,  408 , 173 } , { 1212 ,  734 ,  310 }} ,
    094//              {{  746 ,  452 , 191 } , { 1346 ,  816 ,  345 }} ,
    095//              {{  813 ,  493 , 208 } , { 1500 ,  909 ,  384 }} ,
    096//              {{  919 ,  557 , 235 } , { 1600 ,  970 ,  410 }} ,
    097//              {{  969 ,  587 , 248 } , { 1708 , 1035 ,  438 }} ,
    098//              {{ 1056 ,  640 , 270 } , { 1872 , 1134 ,  480 }} ,
    099//              {{ 1108 ,  672 , 284 } , { 2059 , 1248 ,  528 }} ,
    100//              {{ 1228 ,  744 , 315 } , { 2188 , 1326 ,  561 }} ,
    101//              {{ 1286 ,  779 , 330 } , { 2395 , 1451 ,  614 }} ,
    102//              {{ 1425 ,  864 , 365 } , { 2544 , 1542 ,  652 }} ,
    103//              {{ 1501 ,  910 , 385 } , { 2701 , 1637 ,  692 }} ,
    104//              {{ 1581 ,  958 , 405 } , { 2857 , 1732 ,  732 }} ,
    105//              {{ 1677 , 1016 , 430 } , { 3035 , 1839 ,  778 }} ,
    106//              {{ 1782 , 1080 , 457 } , { 3289 , 1994 ,  843 }} ,
    107//              {{ 1897 , 1150 , 486 } , { 3486 , 2113 ,  894 }} ,
    108//              {{ 2022 , 1226 , 518 } , { 3693 , 2238 ,  947 }} ,
    109//              {{ 2157 , 1307 , 553 } , { 3909 , 2369 , 1002 }} ,
    110//              {{ 2301 , 1394 , 590 } , { 4134 , 2506 , 1060 }} ,
    111//              {{ 2361 , 1431 , 605 } , { 4343 , 2632 , 1113 }} ,
    112//              {{ 2524 , 1530 , 647 } , { 4588 , 2780 , 1176 }} ,
    113//              {{ 2625 , 1591 , 673 } , { 4775 , 2894 , 1224 }} ,
    114//              {{ 2735 , 1658 , 701 } , { 5039 , 3054 , 1292 }} ,
    115//              {{ 2927 , 1774 , 750 } , { 5313 , 3220 , 1362 }} ,
    116//              {{ 3057 , 1852 , 784 } , { 5596 , 3391 , 1435 }} } ;
    117
    118        /** ｴﾗｰ訂正ﾚﾍﾞﾙ ('L','M','Q','H') */
    119        public enum ErrCrct {
    120//      public static enum ErrCrct {
    121//                                      H(0),M(1);
    122                                        /** ｴﾗｰ訂正ﾚﾍﾞﾙ */ L(1),
    123                                        /** ｴﾗｰ訂正ﾚﾍﾞﾙ */ M(0),
    124                                        /** ｴﾗｰ訂正ﾚﾍﾞﾙ */ Q(3),
    125                                        /** ｴﾗｰ訂正ﾚﾍﾞﾙ */ H(2);                                          // 7.2.1.0 (2020/03/13)
    126                                        private int no;
    127                                        /** 初期ｴﾗｰ訂正ﾚﾍﾞﾙ */
    128                                        public static final ErrCrct DEF = M;
    129                                        /**
    130                                         * enum ｺﾝｽﾄﾗｸﾀｰ
    131                                         *
    132                                         * @param       no      番号
    133                                         */
    134                                        ErrCrct( final int no ) { this.no = no; }
    135                                        /**
    136                                         * 番号を取得します。
    137                                         *
    138                                         * @return      番号
    139                                         */
    140                                        public int getNo() { return no; }
    141                                        /**
    142                                         * ﾁｬﾈﾙを取得します。
    143                                         *
    144                                         * @og.rev 7.2.1.0 (2020/03/13) QrcodeImage 見直し。
    145                                         *
    146                                         * @return      ﾁｬﾈﾙｷｬﾗｸﾀ
    147                                         */
    148                                        public char getCh() {
    149                                                final char ch ;
    150                                                switch(this) {
    151                                                        case L:  ch = 'L'; break;                       // 7.2.1.0 (2020/03/13)
    152                                                        case Q:  ch = 'Q'; break;                       // 7.2.1.0 (2020/03/13)
    153                                                        case H:  ch = 'H'; break;
    154                                                        case M:
    155                                                        default: ch = 'M'; break;
    156                                                }
    157                                                return ch ;
    158                                        }
    159                                        /**
    160                                         * ﾁｬﾈﾙに応じたｴﾗｰ訂正を取得します。
    161                                         *
    162                                         * @og.rev 7.2.1.0 (2020/03/13) QrcodeImage 見直し。
    163                                         *
    164                                         * @param       ch      ﾁｬﾈﾙｷｬﾗｸﾀ
    165                                         * @return      ｴﾗｰ訂正
    166                                         */
    167                                        public static ErrCrct get( final char ch ) {
    168                                                final ErrCrct rtn ;
    169                                                switch(ch) {
    170                                                        case 'L': rtn = L; break;                       // 7.2.1.0 (2020/03/13)
    171                                                        case 'Q': rtn = Q; break;                       // 7.2.1.0 (2020/03/13)
    172                                                        case 'H': rtn = H; break;
    173                                                        case 'M':
    174                                                        default:  rtn = M; break;
    175                                                }
    176                                                return rtn ;
    177                                        }
    178        };
    179
    180        // 8.4.1.0 (2023/02/10) Delete
    181//      /** ｴﾝｺｰﾄﾞﾓｰﾄﾞ ('N':数字ﾓｰﾄﾞ 'A':英数字ﾓｰﾄﾞ 'B':8bit byteﾓｰﾄﾞ) */
    182//      public enum EncMode {
    183////    public static enum EncMode {
    184//                                      /** ｴﾝｺｰﾄﾞﾓｰﾄﾞ */ N(0),
    185//                                      /** ｴﾝｺｰﾄﾞﾓｰﾄﾞ */ A(1),
    186//                                      /** ｴﾝｺｰﾄﾞﾓｰﾄﾞ */ B(1);
    187//                                      private int no;
    188//                                      /** 初期ｴﾝｺｰﾄﾞﾓｰﾄﾞ */
    189//                                      public static final EncMode DEF = B;
    190//
    191//                                      /**
    192//                                       * ｴﾝｺｰﾄﾞﾓｰﾄﾞ enum を構築するｺﾝｽﾄﾗｸﾀ
    193//                                       *
    194//                                       * @param       ｴﾝｺｰﾄﾞﾓｰﾄﾞの番号
    195//                                       */
    196//                                      EncMode( final int no ) { this.no = no; }
    197//
    198//                                      /**
    199//                                       * ｴﾝｺｰﾄﾞﾓｰﾄﾞの番号を返します。
    200//                                       * 'N'=0:数字ﾓｰﾄﾞ
    201//                                       * 'A'=1:英数字ﾓｰﾄﾞ
    202//                                       * 'B'=1:8bit byteﾓｰﾄﾞ
    203//                                       *
    204//                                       * @return      ｴﾝｺｰﾄﾞﾓｰﾄﾞの番号
    205//                                       */
    206//                                      public int getNo() { return no; }
    207//
    208//                                      /**
    209//                                       * ｴﾝｺｰﾄﾞﾓｰﾄﾞを表す文字
    210//                                       * 'N':数字ﾓｰﾄﾞ
    211//                                       * 'A':英数字ﾓｰﾄﾞ
    212//                                       * 'B':8bit byteﾓｰﾄﾞ
    213//                                       *
    214//                                       * @return      ｴﾝｺｰﾄﾞﾓｰﾄﾞを指定する文字('N':数字ﾓｰﾄﾞ 'A':英数字ﾓｰﾄﾞ 'B':8bit byteﾓｰﾄﾞ)
    215//                                       */
    216//                                      public char getCh() {
    217//                                              final char ch ;
    218//                                              switch(this) {
    219//                                                      case N:  ch = 'N'; break;
    220//                                                      case A:  ch = 'A'; break;
    221//                                                      case B:
    222//                                                      default: ch = 'B'; break;
    223//                                              }
    224//                                              return ch ;
    225//                                      }
    226//
    227//                                      /**
    228//                                       * ｴﾝｺｰﾄﾞﾓｰﾄﾞを指定する文字から、ｴﾝｺｰﾄﾞﾓｰﾄﾞ enum を作成します。
    229//                                       * 'N':数字ﾓｰﾄﾞ
    230//                                       * 'A':英数字ﾓｰﾄﾞ
    231//                                       * 'B':8bit byteﾓｰﾄﾞ
    232//                                       *
    233//                                       * @param       ch      ｴﾝｺｰﾄﾞﾓｰﾄﾞを指定する文字
    234//                                       * @return      ｴﾝｺｰﾄﾞﾓｰﾄﾞ
    235//                                       */
    236//                                      public static EncMode get( final char ch ) {
    237//                                              final EncMode rtn ;
    238//                                              switch(ch) {
    239//                                                      case 'N': rtn = N; break;
    240//                                                      case 'A': rtn = A; break;
    241//                                                      case 'B':
    242//                                                      default:  rtn = B; break;
    243//                                              }
    244//                                              return rtn ;
    245//                                      }
    246//      };
    247
    248        /** ﾊﾞｰｼﾞｮﾝ (1から40の整数。0を設定すると自動設定になります。) 初期値:{@value} */
    249        public static final int DEF_VERSION = 5;                // 5.7.1.1 (2013/12/13) VERSION ﾁｪｯｸのために、IDを変更します。
    250        /** ｾﾙのﾏｰｼﾞﾝ 初期値:{@value} */
    251        public static final int MARGIN = 4;
    252        /** 1ｾﾙ辺りの塗りつぶしﾋﾟｸｾﾙ 初期値:{@value} */
    253        public static final int PIXEL = 3;
    254        /** 出力ｲﾒｰｼﾞのﾀｲﾌﾟ(PNG/JPEG) 初期値:{@value} */
    255        public static final String IMAGE_TYPE = "PNG";
    256
    257        /** ｴﾝｺｰﾄﾞする文字列 */
    258        private String  qrData;
    259        /** 出力ﾌｧｲﾙ名 */
    260        private String  saveFile;
    261        /** ｲﾒｰｼﾞﾌｧｲﾙ形式(PNG/JPEG) 初期値:PNG */
    262        private String  imgType = IMAGE_TYPE;
    263        /** ｴﾗｰ訂正ﾚﾍﾞﾙ ('L','M','Q','H') 初期値:M */
    264        private ErrCrct errCo   = ErrCrct.DEF;
    265//      private EncMode encMd   = EncMode.DEF;                  // 8.4.1.0 (2023/02/10) Delete
    266        /** ﾊﾞｰｼﾞｮﾝ (2から40の整数) 初期値:5 */
    267        private int             version = DEF_VERSION;                  // 5.7.1.1 (2013/12/13) VERSION ﾁｪｯｸのために、IDを変更します。
    268//      private int             pixel   = PIXEL;                                // 8.4.1.0 (2023/02/10) Delete
    269        /** ﾃｷｽﾄ文字ｴﾝｺｰﾄﾞ */
    270        private String  txtEnc;                                                 // 7.2.3.0 (2020/04/10)
    271
    272        /** ｻｲｽﾞ */
    273        private int             imageSize;
    274
    275        /**
    276         * 初期化ﾒｿｯﾄﾞ
    277         *
    278         * ｴﾗｰ訂正ﾚﾍﾞﾙ:M , ﾏｰｼﾞﾝ:4(ｾﾙ分) , 塗りつぶしﾋﾟｸｾﾙ:3
    279         * <del>ｴﾝｺｰﾄﾞﾓｰﾄﾞ:B(ﾊﾞｲﾅﾘ)</del> ﾊﾞｰｼﾞｮﾝ:5 , ｲﾒｰｼﾞのﾀｲﾌﾟ:PNG
    280         * に初期化されます。
    281         *
    282         * @og.rev 5.7.1.1 (2013/12/13) VERSION ﾁｪｯｸのために、VERSION ⇒ DEF_VERSION に変更します。
    283         * @og.rev 7.2.3.0 (2020/04/10) byteﾓｰﾄﾞ時のﾃｷｽﾄ文字ｴﾝｺｰﾄﾞ。
    284         * @og.rev 8.4.1.0 (2023/02/10) QRｺｰﾄﾞを swetake から ZXing への置換(encodeMode廃止)
    285         *
    286         * @param       qrData          ｴﾝｺｰﾄﾞする文字列(120Byte 以内)
    287         * @param       saveFile        出力ﾌｧｲﾙ名
    288         */
    289        public void init( final String qrData,final String saveFile ) {
    290//              init( qrData,saveFile,DEF_VERSION,EncMode.DEF,ErrCrct.DEF,IMAGE_TYPE,PIXEL );                   // 5.7.1.1 (2013/12/13)
    291//              init( qrData,saveFile,DEF_VERSION,EncMode.DEF,ErrCrct.DEF,IMAGE_TYPE,PIXEL,txtEnc );    // 7.2.3.0 (2020/04/10)
    292                init( qrData,saveFile,DEF_VERSION,ErrCrct.DEF,IMAGE_TYPE,PIXEL,txtEnc );                                // 8.4.1.0 (2023/02/10)
    293        }
    294
    295        /**
    296         * 初期化ﾒｿｯﾄﾞ
    297         *
    298         * ｴﾗｰ訂正ﾚﾍﾞﾙ:M , ﾏｰｼﾞﾝ:4(ｾﾙ分) , 塗りつぶしﾋﾟｸｾﾙ:3
    299         * ｲﾒｰｼﾞのﾀｲﾌﾟ:PNG に初期化されます。
    300         *
    301         * @og.rev 7.2.3.0 (2020/04/10) byteﾓｰﾄﾞ時のﾃｷｽﾄ文字ｴﾝｺｰﾄﾞ。
    302         * @og.rev 8.4.1.0 (2023/02/10) QRｺｰﾄﾞを swetake から ZXing への置換(encodeMode廃止)
    303         *
    304         * @param       qrData          ｴﾝｺｰﾄﾞする文字列(120Byte 以内)
    305         * @param       saveFile        出力ﾌｧｲﾙ名
    306         * @param       version         ﾊﾞｰｼﾞｮﾝ (1から40の整数。0を設定すると自動設定になります。)
    307         * <del>@param  encMd           ｴﾝｺｰﾄﾞﾓｰﾄﾞ ('N':数字ﾓｰﾄﾞ 'A':英数字ﾓｰﾄﾞ 'B':8bit byteﾓｰﾄﾞ)</del>
    308         */
    309//      public void init( final String qrData,final String saveFile,final int version,final EncMode encMd ) {
    310////            init( qrData,saveFile,version,encMd,ErrCrct.DEF,IMAGE_TYPE,PIXEL );
    311//              init( qrData,saveFile,version,encMd,ErrCrct.DEF,IMAGE_TYPE,PIXEL,txtEnc );              // 7.2.3.0 (2020/04/10)
    312//      }
    313        // 8.4.1.0 (2023/02/10) Modify
    314        public void init( final String qrData,final String saveFile,final int version ) {
    315                init( qrData,saveFile,version,ErrCrct.DEF,IMAGE_TYPE,PIXEL,txtEnc );
    316        }
    317
    318        /**
    319         * 初期化ﾒｿｯﾄﾞ。
    320         *
    321         * @og.rev 7.2.3.0 (2020/04/10) textEncode byteﾓｰﾄﾞ時のﾃｷｽﾄ文字ｴﾝｺｰﾄﾞ追加
    322         * @og.rev 8.4.1.0 (2023/02/10) QRｺｰﾄﾞを swetake から ZXing への置換(encodeMode廃止)
    323         *
    324         * @param       qrData          ｴﾝｺｰﾄﾞする文字列(120Byte 以内)
    325         * @param       saveFile        出力ﾌｧｲﾙ名
    326         * @param       version         ﾊﾞｰｼﾞｮﾝ (1から40の整数。0を設定すると自動設定になります。)
    327         * <del>@param  encMd           ｴﾝｺｰﾄﾞﾓｰﾄﾞ('N':数字ﾓｰﾄﾞ 'A':英数字ﾓｰﾄﾞ 'B':8bit byteﾓｰﾄﾞ)</del>
    328         * @param       errCo           ｴﾗｰ訂正ﾚﾍﾞﾙ ('L','M','Q','H')
    329         * @param       imgType         ｲﾒｰｼﾞﾌｧｲﾙ形式(PNG/JPEG)
    330         * @param       pixel           1ｾﾙ辺りの塗りつぶしﾋﾟｸｾﾙ
    331         * @param       txtEnc          ﾃｷｽﾄ文字ｴﾝｺｰﾄﾞ
    332         */
    333//      public void init( final String qrData,final String saveFile,final int version,final EncMode encMd,
    334//                                              final ErrCrct errCo ,final String imgType,final int pixel ) {
    335        public void init( final String qrData,final String saveFile,final int version,                                                  // 8.4.1.0 (2023/02/10)
    336                                                final ErrCrct errCo ,final String imgType,final int pixel,final String txtEnc ) {       // 7.2.3.0 (2020/04/10)
    337
    338                this.qrData             = qrData;
    339                this.saveFile   = saveFile;
    340                this.imgType    = imgType;
    341                this.errCo              = errCo;
    342//              this.encMd              = encMd;                                        // 8.4.1.0 (2023/02/10) Delete
    343                this.version    = version;
    344//              this.pixel              = pixel;                                        // 8.4.1.0 (2023/02/10) Delete
    345                this.txtEnc             = txtEnc;                                       // 7.2.3.0 (2020/04/10)
    346
    347                imageSize = ( MARGIN*2 + 17 + version*4 ) * pixel;
    348        }
    349
    350        // 8.4.1.0 (2023/02/10) Delete
    351//      /**
    352//       * 描画処理を行います。
    353//       *
    354//       * @og.rev 6.4.2.0 (2016/01/29) fukurou.util.StringUtil → fukurou.system.HybsConst に変更
    355//       * @og.rev 7.2.3.0 (2020/04/10) textEncode byteﾓｰﾄﾞ時のﾃｷｽﾄ文字ｴﾝｺｰﾄﾞ追加
    356//       * @og.rev 8.4.1.0 (2023/02/10) QRｺｰﾄﾞを swetake から ZXing への置換(encodeMode廃止)
    357//       *
    358//       * @param       gpx     Graphicsｵﾌﾞｼﾞｪｸﾄ
    359//       */
    360//      @Override
    361//      public void paint( final Graphics gpx ) {
    362//              final Qrcode qrc =new Qrcode();
    363//              qrc.setQrcodeErrorCorrect(errCo.getCh());
    364//              qrc.setQrcodeEncodeMode(encMd.getCh());
    365//              qrc.setQrcodeVersion(version);
    366//
    367//              final Charset txtEncode = txtEnc == null || txtEnc.isEmpty()                    // 7.2.3.0 (2020/04/10)
    368//                                                                      ? HybsConst.DEFAULT_CHARSET                                     // 6.4.2.0 (2016/01/29)
    369//                                                                      : "UTF-8".equals( txtEnc )
    370//                                                                              ? StandardCharsets.UTF_8
    371//                                                                              : Charset.forName( txtEnc ) ;
    372//
    373//      //      final byte[] dt =qrData.getBytes( HybsConst.DEFAULT_CHARSET );                  // 6.4.2.0 (2016/01/29)
    374//              final byte[] dt =qrData.getBytes( txtEncode );                                                  // 7.2.3.0 (2020/04/10)
    375//              final boolean[][] sfg = qrc.calQrcode( dt );
    376//
    377//              final int size = sfg.length;
    378//              final int mgn  = MARGIN*pixel ;
    379//              for( int i=0; i<size; i++ ) {
    380//                      for( int j=0; j<size; j++ ) {
    381//                              if( sfg[j][i] ) {
    382//                                      gpx.fillRect( mgn+j*pixel,mgn+i*pixel,pixel,pixel );
    383//                              }
    384//                      }
    385//              }
    386//      }
    387
    388        /**
    389         * 描画処理を行います。
    390         *
    391         * @og.rev 8.4.1.0 (2023/02/10) QRｺｰﾄﾞを swetake から ZXing への置換(encodeMode廃止)
    392         */
    393        public void saveImage() {
    394//              // 出力用ｲﾒｰｼﾞの生成
    395//              final BufferedImage image = new BufferedImage(imageSize, imageSize, BufferedImage.TYPE_INT_BGR );
    396//
    397//              // ｲﾒｰｼﾞからｸﾞﾗﾌｨｯｸｺﾝﾃｷｽﾄを取得
    398//              final Graphics grph = image.getGraphics();
    399//              grph.setColor( java.awt.Color.WHITE );
    400//              grph.fillRect( 0,0,imageSize, imageSize );
    401//              grph.setColor( java.awt.Color.BLACK );
    402//
    403//              // JEditorPane をｲﾒｰｼﾞに書き込む
    404//              // paintComponent は proteced なので使用できない
    405//              paint( grph );
    406//
    407//              // 使い終わったｸﾞﾗﾌｨｯｸｺﾝﾃｷｽﾄを開放
    408//              grph.dispose();
    409
    410                // 8.4.1.0 (2023/02/10) Modify
    411                try {
    412                        BufferedImage image;
    413                        if( qrData == null || qrData.isEmpty() ){
    414                                image = new BufferedImage(imageSize, imageSize, BufferedImage.TYPE_INT_BGR );
    415                        }
    416                        else {
    417                                final String txtEncode = txtEnc == null || txtEnc.isEmpty()
    418                                                                                ? HybsConst.DEFAULT_CHARSET.displayName()
    419                                                                                : txtEnc;
    420
    421                                final Map<EncodeHintType, Object> hints = new HashMap<>();
    422                                hints.put(EncodeHintType.QR_VERSION, version);                                  // ﾊﾞｰｼﾞｮﾝ
    423                                hints.put(EncodeHintType.ERROR_CORRECTION, errCo.getCh());              // ｴﾗｰ訂正ﾚﾍﾞﾙ(L, M, Q, H)
    424                                hints.put(EncodeHintType.CHARACTER_SET, txtEncode);                             // 文字ｴﾝｺｰﾄﾞ
    425
    426                                final QRCodeWriter writer = new QRCodeWriter();
    427                                final BitMatrix bitMatrix = writer.encode( qrData, BarcodeFormat.QR_CODE, imageSize, imageSize, hints );
    428                                image = MatrixToImageWriter.toBufferedImage(bitMatrix);
    429                        }
    430
    431                        // ｲﾒｰｼﾞの出力 Image I/O を使用
    432                        ImageIO.write( image, imgType, new File( saveFile ) );
    433                } catch ( final WriterException ex) {
    434                        final String errMsg = "QRコードの生成に失敗しました。"
    435                                        + "Data=[" + qrData + "]" ;
    436                        throw new OgRuntimeException( errMsg,ex );
    437                } catch( final IOException ex ) {
    438                        final String errMsg = "イメージファイルの出力に失敗しました。"
    439                                        + "File=[" + saveFile + "]" ;
    440                        throw new OgRuntimeException( errMsg,ex );
    441                }
    442        }
    443
    444        // 8.4.1.0 (2023/02/10) Delete
    445//      /**
    446//       * ﾒｲﾝ処理です。
    447//       * Usage: java org.opengion.fukurou.util.QrcodeImage Encode [SaevFile]
    448//       *
    449//       * @og.rev 8.4.1.0 (2023/02/10) QRｺｰﾄﾞを swetake から ZXing への置換(encodeMode廃止)
    450//       *
    451//       * @param       args    引数文字列配列
    452//       */
    453//      public static void main( final String[] args ) {
    454//              if( args.length == 0 ) {
    455//                      LogWriter.log( "Usage: java org.opengion.fukurou.util.QrcodeImage Encode [SaevFile]" );
    456//                      return ;
    457//              }
    458//
    459//              final String qrcode = args[0];
    460//              final String file   = args.length > 1 ? args[1] : "img.png";
    461//
    462//              final QrcodeImage qrImage = new QrcodeImage();
    463//              qrImage.init( qrcode,file );
    464//              qrImage.saveImage();
    465//      }
    466
    467        // 8.4.1.0 (2023/02/10) Delete
    468//      /**
    469//       * 内部ﾃﾞｰﾀを標準出力へ出力します。
    470//       *
    471//       * @og.rev 7.2.1.0 (2020/03/13) QrcodeImage 見直し。
    472//       * @og.rev 8.4.1.0 (2023/02/10) QRｺｰﾄﾞを swetake から ZXing への置換(encodeMode廃止)
    473//       */
    474//      public static void printQcData() {
    475////            final char[] strJ = new char[] { 'H','M' };
    476//              final char[] strJ = new char[] { 'L','M','Q','H' };                                                     // 7.2.1.0 (2020/03/13)
    477//              final char[] strK = new char[] { 'N','A','B' };
    478//
    479//              for( int i=0; i<QC_DATA.length; i++ ) {
    480//                      System.out.print( "version=[" + (i+1) + "] " );
    481//                      for( int j=0; j<QC_DATA[i].length; j++ ) {
    482//                              final char errCo = strJ[j];
    483//                              for( int k=0; k<QC_DATA[i][j].length; k++ ) {
    484//                                      System.out.print( errCo + strK[k] + "=[" + QC_DATA[i][j][k] + "] " );
    485//                              }
    486//                      }
    487//                      System.out.println();
    488//              }
    489        }
    490
    491        // 8.4.1.0 (2023/02/10) Delete
    492//      /**
    493//       * ﾊﾞｰｼﾞｮﾝ情報を取得します。
    494//       *
    495//       * @og.rev 8.4.1.0 (2023/02/10) QRｺｰﾄﾞを swetake から ZXing への置換(encodeMode廃止)
    496//       *
    497//       * @param       errCo   ｴﾗｰ訂正ﾚﾍﾞﾙ ('L','M','Q','H')
    498//       * @param       encMd   ｴﾝｺｰﾄﾞﾓｰﾄﾞ ('N':数字ﾓｰﾄﾞ 'A':英数字ﾓｰﾄﾞ 'B':8bit byteﾓｰﾄﾞ)
    499//       * @param       len             対象範囲
    500//       * @return      ﾊﾞｰｼﾞｮﾝ情報
    501//       */
    502//      public static int getVersion( final ErrCrct errCo, final EncMode encMd, final int len ) {
    503//              final int errCoInt = errCo.getNo() ;
    504//              final int encMdInt = encMd.getNo() ;
    505//
    506//              int rtn = -1;
    507//              for( int i=0; i<QC_DATA.length; i++ ) {
    508//                      if( QC_DATA[i][errCoInt][encMdInt] >= len ) {
    509//                              rtn = i;
    510//                              break;
    511//                      }
    512//              }
    513//
    514//              if( rtn < 0 ) {
    515//                      final String errMsg = "データ量が対象範囲を超えています。エラーレベルや、モードを調整してください。"
    516//                                              + "ErrCo:" + errCo + " EncMd:" + encMd + " len=[" + len + "]"
    517//                                              + " MaxLen=[" + QC_DATA[QC_DATA.length-1][errCoInt][encMdInt] + "]" ;
    518//                      throw new OgRuntimeException( errMsg );
    519//              }
    520//
    521//              return rtn + 1 ;
    522//      }
    523
    524        // 8.4.1.0 (2023/02/10) Delete
    525//      /**
    526//       * 最大ｻｲｽﾞを取得します。
    527//       *
    528//       * @og.rev 8.4.1.0 (2023/02/10) QRｺｰﾄﾞを swetake から ZXing への置換(encodeMode廃止)
    529//       *
    530//       * @param       version ﾊﾞｰｼﾞｮﾝ情報
    531//       * @param       errCo   ｴﾗｰ訂正ﾚﾍﾞﾙ ('L','M','Q','H')
    532//       * @param       encMd   ｴﾝｺｰﾄﾞﾓｰﾄﾞ ('N':数字ﾓｰﾄﾞ 'A':英数字ﾓｰﾄﾞ 'B':8bit byteﾓｰﾄﾞ)
    533//       * @return      最大ｻｲｽﾞ
    534//       */
    535//      public static int getMaxSize( final int version, final ErrCrct errCo, final EncMode encMd ) {
    536//              final int errCoInt = errCo.getNo() ;
    537//              final int encMdInt = encMd.getNo() ;
    538//
    539//              return QC_DATA[version][errCoInt][encMdInt] ;
    540//      }
    541//}