目次
サンプル・プログラムの実行例
サンプル・プログラム
| qr_sample.php | サンプル・プログラム本体 |
| qr_img.php | QRcode PHP scriptsのPHP7/8対応版 |
| qr_sample.php | サンプル・プログラム本体。 |
| pahooQRimage.php | QRコード(2次元バーコード)作成に関わる暮らす。 使い方は「PHPでQRコードをつくる」などを参照。include_path が通ったディレクトリに配置すること。 |
| バージョン | 更新日 | 内容 |
|---|---|---|
| 4.0.1 | 2025/08/24 | makeCommonBody() -- bug-fix |
| 4.0.0 | 2025/08/16 | pahooQRimage.php,全面改訂。 |
| 3.0 | 2020/12/19 | PHP8対応。全面改訂。 |
| 2.0 | 2008/05/10 | ヒアドキュメント化,UTF-8 |
| 1.1 | 2007/01/20 | XSS対策 |
| バージョン | 更新日 | 内容 |
|---|---|---|
| 2.0.1 | 2025/08/11 | getParam() bug-fix |
| 2.0.0 | 2025/08/11 | pahooLoadEnv() 追加 |
| 1.9.0 | 2025/07/26 | getParam() 引数に$trim追加 |
| 1.8.1 | 2025/03/15 | validRegexPattern() debug |
| 1.8.0 | 2024/11/12 | validRegexPattern() 追加 |
| バージョン | 更新日 | 内容 |
|---|---|---|
| 1.0.1 | 2025/07/29 | text2QRimage() -- bug-fix |
| 1.0.0 | 2025/07/29 | 初版 |
準備:pahooInputData 関数群
また、各種クラウドサービスに登録したときに取得するアカウント情報、アプリケーションパスワードなどを登録した .pahooEnv ファイルから読み込む関数 pahooLoadEnv を備えている。こちらについては、「各種クラウド連携サービス(WebAPI)の登録方法」をご覧いただきたい。
準備:pahooQRimage クラス
pahooQRimage.php
41: class pahooQRimage {
42: public $dataPath; // データファイルのあるパス
43: public $imagePath; // QRコードのイメージフレームのあるパス
44: public $maxQRversion = 40; // 最大バージョン
45: public $maxImageSize = 1480; // QRコードの最大サイズ(一辺のピクセル)
46:
47: public $qrcode_data_string;
48: public $qrcode_module_size;
49: public $qrcode_image_type;
50:
51: public $qrcode_structureappend_n;
52: public $qrcode_structureappend_m;
53: public $qrcode_structureappend_parity;
54: public $qrcode_structureappend_originaldata;
55:
56: function __construct() {
57: $this->dataPath = __DIR__ . '/QRdata';
58: $this->imagePath = __DIR__ . '/QRimage';
59:
60: $this->qrcode_structureappend_n = '';
61: $this->qrcode_structureappend_m = '';
62: $this->qrcode_structureappend_parity = '';
63: $this->qrcode_structureappend_originaldata = '';
64: }
なお、QRコードを生成するのに、"QRimage" フォルダに格納している画像ファイル群と、"QRdata" フォルダに格納しているデータ・ファイル群が必要になる。クラス・ファイル "pahooQRimage.php" と同じディレクトリに配置してほしい。
解説:各種定数
qr_sample.php
55: // 各種定数(START) ===========================================================
56:
57: // 表示幅(ピクセル)
58: define('WIDTH', 500);
59:
60: // 入力できる最大文字数
61: define('MAX_TEXT_LENGTH', 1000);
62:
63: // メッセージ(初期値)
64: define('DEF_TEXT', 'ぱふぅ家のホームページ https://www.pahoo.org/');
65:
66: // QRコードのサイズ(単位:ピクセル)
67: define('WIDTH_QRCODE', 300);
68:
69: // 各種定数(END) ===========================================================
解説:text2QRimageメソッド
引数として、QRコードのサイズや画像形式、ECCレベル、QRコードコードのバージョンを指定できる。
pahooQRimage.php
66: /**
67: * テキストをQRイメージデータに変換する.
68: * @param string $text QRコードにしたいテキスト
69: * @param int $imageSize QRコードの一辺のサイズ(単位:ピクセル)(省略時 200)
70: * @param string $imageType 画像形式(jpeg, png)(省略時 png)
71: * @param string $eccLevel ECCレベル(L, M, Q, H)(省略時 M)
72: * @param int $versionQR QRコードのバージョン(0:自動, 1〜40)(省略時 0)
73: * @return string 応答データ/FALSE=失敗
74: */
75: function text2QRimage($text, $imageSize=200, $imageType='png', $eccLevel='M', $versionQR=0) {
76: // テキストのバリデーション
77: $sourText = rawurldecode($text);
78: $data_length = strlen($sourText);
79: if ($data_length <= 0) {
80: throw new Exception($imageSize . 'テキストがありません');
81: return FALSE;
82: }
83:
84: // 画像サイズのバリデーション
85: if (($imageSize < 1) || ($imageSize > $this->maxImageSize)) {
86: throw new Exception($imageSize . ' -- 対応していない画像サイズです');
87: return FALSE;
88: }
89:
90: // 画像形式のバリデーション
91: $imageTypeList = [ 'jpeg', 'png' ];
92: $imageType = strtolower($imageType);
93: if (array_search($imageType, $imageTypeList) === FALSE) {
94: throw new Exception($imageType . ' -- 対応していない画像形式です');
95: return FALSE;
96: }
97:
98: // QRコードのバージョンのバリデーション
99: if (! is_numeric($versionQR)) {
100: $versionQR = 0;
101: }
102: if ($versionQR > $this->maxQRversion) {
103: throw new Exception($imageType . ' -- 対応していないQRバージョンです');
104: return FALSE;
105: }
106:
107: $data_counter = 0;
108: if ($this->qrcode_structureappend_n > 1
109: && $this->qrcode_structureappend_n <= 16
110: && $this->qrcode_structureappend_m > 0
111: && $this->qrcode_structureqppend_m <= 16) {
112:
113: $data_value[0] = 3;
114: $data_bits[0] = 4;
115:
116: $data_value[1] = $this->qrcode_structureappend_m - 1;
117: $data_bits[1] = 4;
118:
119: $data_value[2] = $this->qrcode_structureappend_n - 1;
120: $data_bits[2] = 4;
121:
122: $originaldata_length = strlen($this->qrcode_structureappend_originaldata);
123: if ($originaldata_length > 1) {
124: $this->qrcode_structureappend_parity = 0;
125: $i=0;
126: while ($i<$originaldata_length){
127: $this->qrcode_structureappend_parity=($this->qrcode_structureappend_parity ^ ord(substr($this->qrcode_structureappend_originaldata,$i,1)));
128: $i++;
129: }
130: }
131:
132: $data_value[3]=$this->qrcode_structureappend_parity;
133: $data_bits[3]=8;
134:
135: $data_counter=4;
136: }
137:
138: $data_bits[$data_counter] = 4;
139:
140: /* --- determine encode mode */
141:
142: if (preg_match('/[^0-9]/ui', $sourText)) {
143: if (preg_match('/[^0-9A-Z \$\*\%\+\-\.\/\:]/ui', $sourText)) {
144:
145: /* --- 8bit byte mode */
146:
147: $codeword_num_plus=array(0,0,0,0,0,0,0,0,0,0,
148: 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
149: 8,8,8,8,8,8,8,8,8,8,8,8,8,8);
150:
151: $data_value[$data_counter]=4;
152: $data_counter++;
153: $data_value[$data_counter]=$data_length;
154: $data_bits[$data_counter]=8; /* #version 1-9 */
155: $codeword_num_counter_value=$data_counter;
156:
157: $data_counter++;
158: $i=0;
159: while ($i<$data_length){
160: $data_value[$data_counter] = ord(substr($sourText,$i, 1));
161: $data_bits[$data_counter] = 8;
162: $data_counter++;
163: $i++;
164: }
165: } else {
166:
167: /* ---- alphanumeric mode */
168:
169: $codeword_num_plus=array(0,0,0,0,0,0,0,0,0,0,
170: 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
171: 4,4,4,4,4,4,4,4,4,4,4,4,4,4);
172:
173: $data_value[$data_counter]=2;
174: $data_counter++;
175: $data_value[$data_counter]=$data_length;
176: $data_bits[$data_counter]=9; /* #version 1-9 */
177: $codeword_num_counter_value=$data_counter;
178:
179:
180: $alphanumeric_character_hash=array("0"=>0,"1"=>1,"2"=>2,"3"=>3,"4"=>4,
181: "5"=>5,"6"=>6,"7"=>7,"8"=>8,"9"=>9,"A"=>10,"B"=>11,"C"=>12,"D"=>13,"E"=>14,
182: "F"=>15,"G"=>16,"H"=>17,"I"=>18,"J"=>19,"K"=>20,"L"=>21,"M"=>22,"N"=>23,
183: "O"=>24,"P"=>25,"Q"=>26,"R"=>27,"S"=>28,"T"=>29,"U"=>30,"V"=>31,
184: "W"=>32,"X"=>33,"Y"=>34,"Z"=>35," "=>36,"$"=>37,"%"=>38,"*"=>39,
185: "+"=>40,"-"=>41,"."=>42,"/"=>43,":"=>44);
186:
187: $i=0;
188: $data_counter++;
189: while ($i<$data_length){
190: if (($i %2)==0){
191: $data_value[$data_counter]=$alphanumeric_character_hash[substr($sourText, $i ,1)];
192: $data_bits[$data_counter]=6;
193: } else {
194: $data_value[$data_counter]=$data_value[$data_counter]*45+$alphanumeric_character_hash[substr($sourText, $i, 1)];
195: $data_bits[$data_counter]=11;
196: $data_counter++;
197: }
198: $i++;
199: }
200: }
201: } else {
202:
203: /* ---- numeric mode */
204:
205: $codeword_num_plus=array(0,0,0,0,0,0,0,0,0,0,
206: 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
207: 4,4,4,4,4,4,4,4,4,4,4,4,4,4);
208:
209: $data_value[$data_counter]=1;
210: $data_counter++;
211: $data_value[$data_counter]=$data_length;
212: $data_bits[$data_counter]=10; /* #version 1-9 */
213: $codeword_num_counter_value=$data_counter;
214:
215: $i=0;
216: $data_counter++;
217: while ($i<$data_length){
218: if (($i % 3)==0){
219: $data_value[$data_counter]=substr($sourText, $i, 1);
220: $data_bits[$data_counter]=4;
221: } else {
222: $data_value[$data_counter]=$data_value[$data_counter]*10+substr($sourText, $i, 1);
223: if (($i % 3)==1){
224: $data_bits[$data_counter]=7;
225: } else {
226: $data_bits[$data_counter]=10;
227: $data_counter++;
228: }
229: }
230: $i++;
231: }
232: }
233: if (isset($data_bits[$data_counter]) && ($data_bits[$data_counter] > 0)) {
234: $data_counter++;
235: }
236: $i=0;
237: $total_data_bits=0;
238: while($i<$data_counter){
239: $total_data_bits+=$data_bits[$i];
240: $i++;
241: }
242:
243:
244: $ecc_character_hash=array("L"=>"1",
245: "l"=>"1",
246: "M"=>"0",
247: "m"=>"0",
248: "Q"=>"3",
249: "q"=>"3",
250: "H"=>"2",
251: "h"=>"2");
252:
253: $ec = @$ecc_character_hash[$eccLevel];
254:
255: if (!$ec){$ec=0;}
256:
257: $max_data_bits_array=array(
258: 0,128,224,352,512,688,864,992,1232,1456,1728,
259: 2032,2320,2672,2920,3320,3624,4056,4504,5016,5352,
260: 5712,6256,6880,7312,8000,8496,9024,9544,10136,10984,
261: 11640,12328,13048,13800,14496,15312,15936,16816,17728,18672,
262:
263: 152,272,440,640,864,1088,1248,1552,1856,2192,
264: 2592,2960,3424,3688,4184,4712,5176,5768,6360,6888,
265: 7456,8048,8752,9392,10208,10960,11744,12248,13048,13880,
266: 14744,15640,16568,17528,18448,19472,20528,21616,22496,23648,
267:
268: 72,128,208,288,368,480,528,688,800,976,
269: 1120,1264,1440,1576,1784,2024,2264,2504,2728,3080,
270: 3248,3536,3712,4112,4304,4768,5024,5288,5608,5960,
271: 6344,6760,7208,7688,7888,8432,8768,9136,9776,10208,
272:
273: 104,176,272,384,496,608,704,880,1056,1232,
274: 1440,1648,1952,2088,2360,2600,2936,3176,3560,3880,
275: 4096,4544,4912,5312,5744,6032,6464,6968,7288,7880,
276: 8264,8920,9368,9848,10288,10832,11408,12016,12656,13328
277: );
278:
279: if (! $versionQR) {
280: /* #--- auto version select */
281: $i = 1 + 40 * $ec;
282: $j = $i + 39;
283: $versionQR = 1;
284: while ($i<=$j){
285: if (($max_data_bits_array[$i])>=$total_data_bits+$codeword_num_plus[$versionQR] ){
286: $max_data_bits=$max_data_bits_array[$i];
287: break;
288: }
289: $i++;
290: $versionQR++;
291: }
292: } else {
293: $max_data_bits=$max_data_bits_array[$versionQR + 40 * $ec];
294: }
295:
296: $total_data_bits+=$codeword_num_plus[$versionQR];
297: $data_bits[$codeword_num_counter_value]+=$codeword_num_plus[$versionQR];
298:
299: $max_codewords_array=array(0,26,44,70,100,134,172,196,242,
300: 292,346,404,466,532,581,655,733,815,901,991,1085,1156,
301: 1258,1364,1474,1588,1706,1828,1921,2051,2185,2323,2465,
302: 2611,2761,2876,3034,3196,3362,3532,3706);
303:
304: $max_codewords=$max_codewords_array[$versionQR];
305: $max_modules_1side=17+($versionQR << 2);
306:
307: $matrix_remain_bit=array(0,0,7,7,7,7,7,0,0,0,0,0,0,0,3,3,3,3,3,3,3,
308: 4,4,4,4,4,4,4,3,3,3,3,3,3,3,0,0,0,0,0,0);
309:
310: /* ---- read version ECC data file */
311:
312: $byte_num=$matrix_remain_bit[$versionQR]+($max_codewords << 3);
313: $filename=$this->dataPath . "/qrv" . $versionQR . "_" . $ec . ".dat";
314:
315: $fp1 = fopen ($filename, "rb");
316: $matx=fread($fp1,$byte_num);
317: $maty=fread($fp1,$byte_num);
318: $masks=fread($fp1,$byte_num);
319: $fi_x=fread($fp1,15);
320: $fi_y=fread($fp1,15);
321: $rs_ecc_codewords=ord(fread($fp1,1));
322: $rso=fread($fp1,128);
323: fclose($fp1);
324:
325: $matrix_x_array=unpack("C*",$matx);
326: $matrix_y_array=unpack("C*",$maty);
327: $mask_array=unpack("C*",$masks);
328:
329: $rs_block_order=unpack("C*",$rso);
330:
331: $format_information_x2=unpack("C*",$fi_x);
332: $format_information_y2=unpack("C*",$fi_y);
333:
334: $format_information_x1=array(0,1,2,3,4,5,7,8,8,8,8,8,8,8,8);
335: $format_information_y1=array(8,8,8,8,8,8,8,8,7,5,4,3,2,1,0);
336:
337: $max_data_codewords=($max_data_bits >>3);
338:
339: $filename = $this->dataPath."/rsc".$rs_ecc_codewords.".dat";
340: $fp0 = fopen ($filename, "rb");
341: $i=0;
342: while ($i<256) {
343: $rs_cal_table_array[$i]=fread ($fp0,$rs_ecc_codewords);
344: $i++;
345: }
346: fclose ($fp0);
347:
348: /* --- set terminator */
349:
350: if ($total_data_bits<=$max_data_bits-4){
351: $data_value[$data_counter]=0;
352: $data_bits[$data_counter]=4;
353: } else {
354: if ($total_data_bits<$max_data_bits){
355: $data_value[$data_counter]=0;
356: $data_bits[$data_counter]=$max_data_bits-$total_data_bits;
357: } else {
358: if ($total_data_bits>$max_data_bits){
359: trigger_error("QRcode : Overflow error",E_USER_ERROR);
360: exit;
361: }
362: }
363: }
364:
365: /* ----divide data by 8bit */
366:
367: $i=0;
368: $codewords_counter=0;
369: $codewords[0]=0;
370: $remaining_bits=8;
371:
372: while ($i<=$data_counter) {
373: $buffer=@$data_value[$i];
374: $buffer_bits=@$data_bits[$i];
375:
376: $flag=1;
377: while ($flag) {
378: if ($remaining_bits>$buffer_bits){
379: $codewords[$codewords_counter]=((@$codewords[$codewords_counter]<<$buffer_bits) | $buffer);
380: $remaining_bits-=$buffer_bits;
381: $flag=0;
382: } else {
383: $buffer_bits-=$remaining_bits;
384: $codewords[$codewords_counter]=(($codewords[$codewords_counter] << $remaining_bits) | ($buffer >> $buffer_bits));
385:
386: if ($buffer_bits==0) {
387: $flag=0;
388: } else {
389: $buffer= ($buffer & ((1 << $buffer_bits)-1) );
390: $flag=1;
391: }
392:
393: $codewords_counter++;
394: if ($codewords_counter<$max_data_codewords-1){
395: $codewords[$codewords_counter]=0;
396: }
397: $remaining_bits=8;
398: }
399: }
400: $i++;
401: }
402: if ($remaining_bits!=8) {
403: $codewords[$codewords_counter]=$codewords[$codewords_counter] << $remaining_bits;
404: } else {
405: $codewords_counter--;
406: }
407:
408: /* ---- set padding character */
409:
410: if ($codewords_counter<$max_data_codewords-1){
411: $flag=1;
412: while ($codewords_counter<$max_data_codewords-1){
413: $codewords_counter++;
414: if ($flag==1) {
415: $codewords[$codewords_counter]=236;
416: } else {
417: $codewords[$codewords_counter]=17;
418: }
419: $flag=$flag*(-1);
420: }
421: }
422:
423: /* ---- RS-ECC prepare */
424:
425: $i=0;
426: $j=0;
427: $rs_block_number=0;
428: $rs_temp[0]="";
429:
430: while($i<$max_data_codewords){
431:
432: $rs_temp[$rs_block_number].=chr($codewords[$i]);
433: $j++;
434:
435: if ($j>=$rs_block_order[$rs_block_number+1]-$rs_ecc_codewords){
436: $j=0;
437: $rs_block_number++;
438: $rs_temp[$rs_block_number]="";
439: }
440: $i++;
441: }
442:
443:
444: /*
445: #
446: # RS-ECC main
447: #
448: */
449:
450: $rs_block_number=0;
451: $rs_block_order_num=count($rs_block_order);
452:
453: while ($rs_block_number<$rs_block_order_num){
454:
455: $rs_codewords=$rs_block_order[$rs_block_number+1];
456: $rs_data_codewords=$rs_codewords-$rs_ecc_codewords;
457:
458: $rstemp=$rs_temp[$rs_block_number].str_repeat(chr(0),$rs_ecc_codewords);
459: $padding_data=str_repeat(chr(0),$rs_data_codewords);
460:
461: $j=$rs_data_codewords;
462: while($j>0){
463: $first=ord(substr($rstemp,0,1));
464:
465: if ($first){
466: $left_chr=substr($rstemp,1);
467: $cal=$rs_cal_table_array[$first].$padding_data;
468: $rstemp=$left_chr ^ $cal;
469: } else {
470: $rstemp=substr($rstemp,1);
471: }
472:
473: $j--;
474: }
475:
476: $codewords=array_merge($codewords,unpack("C*",$rstemp));
477:
478: $rs_block_number++;
479: }
480:
481: /* ---- flash matrix */
482:
483: $i=0;
484: while ($i<$max_modules_1side){
485: $j=0;
486: while ($j<$max_modules_1side){
487: $matrix_content[$j][$i]=0;
488: $j++;
489: }
490: $i++;
491: }
492:
493: /* --- attach data */
494:
495: $i=0;
496: while ($i<$max_codewords){
497: $codeword_i=$codewords[$i];
498: $j=8;
499: while ($j>=1){
500: $codeword_bits_number=($i << 3) + $j;
501: $matrix_content[ $matrix_x_array[$codeword_bits_number] ][ $matrix_y_array[$codeword_bits_number] ]=((255*($codeword_i & 1)) ^ $mask_array[$codeword_bits_number] );
502: $codeword_i= $codeword_i >> 1;
503: $j--;
504: }
505: $i++;
506: }
507:
508: $matrix_remain=$matrix_remain_bit[$versionQR];
509: while ($matrix_remain){
510: $remain_bit_temp = $matrix_remain + ( $max_codewords <<3);
511: $matrix_content[ $matrix_x_array[$remain_bit_temp] ][ $matrix_y_array[$remain_bit_temp] ] = ( 255 ^ $mask_array[$remain_bit_temp] );
512: $matrix_remain--;
513: }
514:
515: #--- mask select
516:
517: $min_demerit_score=0;
518: $hor_master="";
519: $ver_master="";
520: $k=0;
521: while($k<$max_modules_1side){
522: $l=0;
523: while($l<$max_modules_1side){
524: $hor_master=$hor_master.chr($matrix_content[$l][$k]);
525: $ver_master=$ver_master.chr($matrix_content[$k][$l]);
526: $l++;
527: }
528: $k++;
529: }
530: $i=0;
531: $all_matrix=$max_modules_1side * $max_modules_1side;
532: while ($i<8){
533: $demerit_n1=0;
534: $ptn_temp=array();
535: $bit= 1<< $i;
536: $bit_r=(~$bit)&255;
537: $bit_mask=str_repeat(chr($bit),$all_matrix);
538: $hor = $hor_master & $bit_mask;
539: $ver = $ver_master & $bit_mask;
540:
541: $ver_shift1=$ver.str_repeat(chr(170),$max_modules_1side);
542: $ver_shift2=str_repeat(chr(170),$max_modules_1side).$ver;
543: $ver_shift1_0=$ver.str_repeat(chr(0),$max_modules_1side);
544: $ver_shift2_0=str_repeat(chr(0),$max_modules_1side).$ver;
545: $ver_or=chunk_split(~($ver_shift1 | $ver_shift2),$max_modules_1side,chr(170));
546: $ver_and=chunk_split(~($ver_shift1_0 & $ver_shift2_0),$max_modules_1side,chr(170));
547:
548: $hor=chunk_split(~$hor,$max_modules_1side,chr(170));
549: $ver=chunk_split(~$ver,$max_modules_1side,chr(170));
550: $hor=$hor.chr(170).$ver;
551:
552: $n1_search="/".str_repeat(chr(255),5)."+|".str_repeat(chr($bit_r),5)."+/";
553: $n3_search=chr($bit_r).chr(255).chr($bit_r).chr($bit_r).chr($bit_r).chr(255).chr($bit_r);
554:
555: $demerit_n3=substr_count($hor,$n3_search)*40;
556: $demerit_n4=floor(abs(( (100* (substr_count($ver,chr($bit_r))/($byte_num)) )-50)/5))*10;
557:
558:
559: $n2_search1="/".chr($bit_r).chr($bit_r)."+/";
560: $n2_search2="/".chr(255).chr(255)."+/";
561: $demerit_n2=0;
562: preg_match_all($n2_search1,$ver_and,$ptn_temp);
563: foreach($ptn_temp[0] as $str_temp){
564: $demerit_n2+=(strlen($str_temp)-1);
565: }
566: $ptn_temp=array();
567: preg_match_all($n2_search2,$ver_or,$ptn_temp);
568: foreach($ptn_temp[0] as $str_temp){
569: $demerit_n2+=(strlen($str_temp)-1);
570: }
571: $demerit_n2*=3;
572:
573: $ptn_temp=array();
574:
575: preg_match_all($n1_search,$hor,$ptn_temp);
576: foreach($ptn_temp[0] as $str_temp){
577: $demerit_n1+=(strlen($str_temp)-2);
578: }
579:
580: $demerit_score=$demerit_n1+$demerit_n2+$demerit_n3+$demerit_n4;
581:
582: if ($demerit_score<=$min_demerit_score || $i==0){
583: $mask_number=$i;
584: $min_demerit_score=$demerit_score;
585: }
586:
587: $i++;
588: }
589:
590: $mask_content=1 << $mask_number;
591:
592: # --- format information
593:
594: $format_information_value=(($ec << 3) | $mask_number);
595: $format_information_array=array("101010000010010","101000100100101",
596: "101111001111100","101101101001011","100010111111001","100000011001110",
597: "100111110010111","100101010100000","111011111000100","111001011110011",
598: "111110110101010","111100010011101","110011000101111","110001100011000",
599: "110110001000001","110100101110110","001011010001001","001001110111110",
600: "001110011100111","001100111010000","000011101100010","000001001010101",
601: "000110100001100","000100000111011","011010101011111","011000001101000",
602: "011111100110001","011101000000110","010010010110100","010000110000011",
603: "010111011011010","010101111101101");
604: $i=0;
605: while ($i<15){
606: $content=substr($format_information_array[$format_information_value],$i,1);
607:
608: $matrix_content[$format_information_x1[$i]][$format_information_y1[$i]]=$content * 255;
609: $matrix_content[$format_information_x2[$i+1]][$format_information_y2[$i+1]]=$content * 255;
610: $i++;
611: }
612:
613:
614: $mib = $max_modules_1side + 8;
615: // $qrcode_image_size = $mib * $this->qrcode_module_size;
616:
617: $output_image = imagecreate($imageSize, $imageSize);
618:
619: $this->imagePath = $this->imagePath . '/qrv' . $versionQR . '.png';
620:
621: $base_image = imagecreatefrompng($this->imagePath);
622:
623: $col[1] = ImageColorAllocate($base_image, 0, 0, 0);
624: $col[0] = ImageColorAllocate($base_image, 255, 255, 255);
625:
626: $i = 4;
627: $mxe = 4 + $max_modules_1side;
628: $ii = 0;
629: while ($i<$mxe){
630: $j = 4;
631: $jj = 0;
632: while ($j < $mxe){
633: if ($matrix_content[$ii][$jj] & $mask_content){
634: ImageSetPixel($base_image,$i,$j,$col[1]);
635: }
636: $j++;
637: $jj++;
638: }
639: $i++;
640: $ii++;
641: }
642:
643: /*
644: #--- output image
645: #
646: */
647: //Header("Content-type: image/" . $imageType);
648: imagecopyresized($output_image, $base_image, 0, 0, 0, 0, $imageSize, $imageSize, $mib, $mib);
649: if ($imageType == 'jpeg'){
650: $mimeType = 'image' . $imageType;
651: ob_start();
652: imagejpeg($output_image);
653: $imageData = ob_get_clean();
654: } else {
655: $mimeType = 'image' . $imageType;
656: ob_start();
657: imagepng($output_image);
658: $imageData = ob_get_clean();
659: }
660:
661: return $imageData;
662: }
解説:メイン・プログラム
qr_sample.php
317: // インスタンス生成
318: $pqi = new pahooQRimage();
319:
320: // パラメータ取得
321: $errmsg = '';
322: $text = getValidString('text', $errmsg, DEF_TEXT, 0, MAX_TEXT_LENGTH);
323:
324: // QRコード生成
325: if (($errmsg === '') && ($text !== '')) {
326: $imageData = $pqi->text2QRimage($text, WIDTH_QRCODE);
327: $base64 = $pqi->image2base64($imageData);
328: } else {
329: $url = '';
330: }
331:
332: // 表示HTML生成
333: $HtmlBody = makeCommonBody($text, $base64, $errmsg);
334:
335: // 表示処理
336: echo $HtmlHeader;
337: echo $HtmlBody;
338: echo $HtmlFooter;
339:
340: // インスタンス解放
341: $pqi = NULL;
解説:HTML BODYを作成する
QRコードは、imgタグの中でQRimageのリクエストURLを呼び出している。
qr_sample.php
225: /**
226: * HTML BODYを作成する
227: * @param string $text QRコードにするテキスト
228: * @param string $base64 QRコード画像データ(BASE64エンコード)
229: * @param string $errmsg エラー・メッセージ
230: * @return string HTML BODY
231: */
232: function makeCommonBody($text, $base64, $errmsg) {
233: $myself = MYSELF;
234: $refere = REFERENCE;
235: $width = WIDTH;
236: $title = TITLE;
237: $maxChars = MAX_TEXT_LENGTH + 10;
238: $version = '<span style="font-size:small;">' . date('Y/m/d版', filemtime(__FILE__)) . '</span>';
239: $debug = '';
240:
241: // QRコード(画像)のタグ
242: if ($errmsg === '') {
243: $res =<<< EOT
244: <img src="{$base64}" alt="base64">
245:
246: EOT;
247: } else {
248: $res =<<< EOT
249: <p style="color:ref;">{$errmsg}</p>
250:
251: EOT;
252: }
253:
254: // デバッグ情報
255: if (! FLAG_RELEASE) {
256: $phpver = phpversion();
257: $debug =<<< EOT
258: <div>
259: <span style="font-weight:bold;">★デバックモードで動作中...</span><br>
260: PHPver : {$phpver}
261: </div>
262:
263: EOT;
264: }
265: $body =<<< EOT
266: <body>
267: <h2>{$title} {$version}</h2>
268: <form name="myform" method="post" action="{$myself}" enctype="multipart/form-data">
269: テキスト<br>
270: <textarea id="text" name="text" maxlength="{$maxChars}">
271: {$text}
272: </textarea>
273:
274: <div class="counter">
275: <input type="submit" name="exec" id="exec" value="作成">
276:
277: <span id="counterContainar">
278: <span id="charCounter"></span>
279: <svg class="progress" viewBox="0 0 36 36">
280: <path
281: d="M18 2a16 16 0 1 1 0 32 16 16 0 0 1 0-32"
282: fill="none"
283: stroke="lightsteelblue"
284: stroke-width="4.0"
285: />
286: <path
287: id="progressBar"
288: d="M18 2a16 16 0 1 1 0 32 16 16 0 0 1 0-32"
289: fill="none"
290: stroke="royalblue"
291: stroke-width="4.0"
292: stroke-dasharray="100, 100"
293: />
294: </svg>
295: </span>
296: </div>
297:
298: {$res}
299: </form>
300:
301: <div style="border-style:solid; border-width:1px; margin:20px 0px 0px 0px; padding:5px; width:{$width}px; font-size:small; overflow-wrap:break-word; word-break:break-all;">
302: <h3>使い方</h3>
303: <ol>
304: <li>[<span style="font-weight:bold;">テキスト</span>]にQRコードにしたいテキストを入力し,[<span style="font-weight:bold;">作成</span>] ボタンを押してください.</li>
305: <li>QRコードを表示します.</li>
306: </ol>
307: ※参考サイト:<a href="{$refere}">{$refere}</a>
308: {$debug}
309: </div>
310: </body>
311:
312: EOT;
313: return $body;
314: }
参考サイト
- QRコード・バーコード:Y.Swetake さん
- QR code.com:デンソーウェーブ

ぱふぅ家のホームページもスマホに対応しているので、PC版のトップページに QR コードを表示してみようと考えた。
Y.Swetake さんのサイトに PHPのプログラムが公開されている。今回は、これを利用させていただくことにした。なお、このライブラリを利用するには、GD 2.0以上 が組み込まれている必要がある。
なお、QR コードは株式会社デンソーウェーブが開発し、その規格・仕様自体はオープンであるが、QR コードという名称だけはデンソーウェーブの登録商標となっている。
(2025年8月16日)pahooQRimage.php,全面改訂。