概要
QRコードの画像データを返すWeb APIのサンプルコードです。ライブラリには[zxing] (https://github.com/zxing/zxing)を利用しました。
環境
- Windows7 (64bit)
- Java 1.8.0_65
- Spring-Boot 1.3.0
- zxing 3.2.1
準備
プロジェクトにzxingライブラリを加えます。
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.2.1</version>
</dependency>
サンプルコード
API
リクエストパラメータで指定された文字列をQRコードにした画像データを返すAPIバージョンです。
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Hashtable;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
@Controller
@RequestMapping(value = "/image")
public class ImageController {
@RequestMapping(value = "/qr/{contents}", method = RequestMethod.GET)
public ResponseEntity<byte[]> qr(@PathVariable(value="contents") String contents) {
try {
byte[] res = toByteArray(contents);
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_PNG);
return new ResponseEntity<byte[]>(res, headers, HttpStatus.CREATED);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private byte[] toByteArray(String contents) throws IOException, WriterException {
BarcodeFormat format = BarcodeFormat.QR_CODE;
int width = 160;
int height = 160;
Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
try (ByteArrayOutputStream output = new ByteArrayOutputStream()){
QRCodeWriter writer = new QRCodeWriter();
BitMatrix bitMatrix = writer.encode(contents, format, width, height, hints);
MatrixToImageWriter.writeToStream(bitMatrix, "png", output);
return output.toByteArray();
}
}
}
実行
アプリケーションを実行して、下記のURLにアクセスするとrubytomato
という文字列をQRコードにした画像データのレスポンスが得られます。
サンプル画像
dataURL
画像データをBase64エンコードすることでdataURLで表示させることができます。
Base64エンコードのライブラリにはcommons-codecを使用しました。
pom.xml
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
@RequestMapping(value = "/data/{contents}", method = RequestMethod.GET)
public String data(@PathVariable(value="contents") String contents, Model model) {
try {
byte[] res = conv(contents);
String encodedStr64 = Base64.encodeBase64String(res);
model.addAttribute("dataUrl", encodedStr64);
} catch (Exception e) {
e.printStackTrace();
}
return "Image/data";
}
テンプレートのimgタグにdataスキームを指定しBase64エンコードしたデータをセットすることで画像データを表示します。
template
<img th:src="|data:image/png;base64,${dataUrl}|" />
実行