001/* 002 * Copyright (C) Photon Vision. 003 * 004 * This program is free software: you can redistribute it and/or modify 005 * it under the terms of the GNU General Public License as published by 006 * the Free Software Foundation, either version 3 of the License, or 007 * (at your option) any later version. 008 * 009 * This program is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 * GNU General Public License for more details. 013 * 014 * You should have received a copy of the GNU General Public License 015 * along with this program. If not, see <https://www.gnu.org/licenses/>. 016 */ 017 018package org.photonvision.vision.calibration; 019 020import com.fasterxml.jackson.annotation.JsonIgnore; 021import com.fasterxml.jackson.annotation.JsonProperty; 022import java.util.Base64; 023import org.opencv.core.Mat; 024import org.opencv.core.MatOfByte; 025import org.opencv.imgcodecs.Imgcodecs; 026import org.photonvision.vision.opencv.Releasable; 027 028/** JSON-serializable image. Data is stored as base64-encoded PNG data. */ 029public class JsonImageMat implements Releasable { 030 public final int rows; 031 public final int cols; 032 public final int type; 033 034 // We store image data as a base64-encoded PNG inside a Java string. This lets us serialize it 035 // without too much overhead and still use JSON. 036 public final String data; 037 038 // Cached matrices to avoid object recreation 039 @JsonIgnore private Mat wrappedMat = null; 040 041 public JsonImageMat(Mat mat) { 042 this.rows = mat.rows(); 043 this.cols = mat.cols(); 044 this.type = mat.type(); 045 046 // Convert from Mat -> png byte array -> base64 047 var buf = new MatOfByte(); 048 Imgcodecs.imencode(".png", mat, buf); 049 data = Base64.getEncoder().encodeToString(buf.toArray()); 050 buf.release(); 051 } 052 053 public JsonImageMat( 054 @JsonProperty("rows") int rows, 055 @JsonProperty("cols") int cols, 056 @JsonProperty("type") int type, 057 @JsonProperty("data") String data) { 058 this.rows = rows; 059 this.cols = cols; 060 this.type = type; 061 this.data = data; 062 } 063 064 @JsonIgnore 065 public Mat getAsMat() { 066 if (wrappedMat == null) { 067 // Convert back from base64 string -> png -> Mat 068 var bytes = Base64.getDecoder().decode(data); 069 var pngData = new MatOfByte(bytes); 070 this.wrappedMat = Imgcodecs.imdecode(pngData, Imgcodecs.IMREAD_COLOR); 071 } 072 return this.wrappedMat; 073 } 074 075 @Override 076 public void release() { 077 if (wrappedMat != null) wrappedMat.release(); 078 } 079 080 @Override 081 public String toString() { 082 return "JsonImageMat [rows=" 083 + rows 084 + ", cols=" 085 + cols 086 + ", type=" 087 + type 088 + ", datalen=" 089 + data.length() 090 + "]"; 091 } 092}