我有一个名为QRGenerator的“静态类”,其目的是生成BitMatrix对象并从中生成BufferedImage对象。这是它的代码:
package ericsonwrp.republica.vintage.caixa;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.EnumMap;
import java.util.Map;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
public class QRGenerator {
private static BufferedImage image = null;
private static int size = 250;
private static BitMatrix byteMatrix = null;
public static BitMatrix generateBitMatrix(String codeText) {
try {
Map<EncodeHintType, Object> hintMap = new EnumMap<EncodeHintType, Object>(EncodeHintType.class);
hintMap.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hintMap.put(EncodeHintType.MARGIN, 1);
hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
QRCodeWriter qrCodeWriter = new QRCodeWriter();
byteMatrix = qrCodeWriter.encode(codeText, BarcodeFormat.QR_CODE, size,
size, hintMap);
} catch (WriterException e) {
e.printStackTrace();
}
return byteMatrix;
}
public static BufferedImage generateImage(BitMatrix byteMatrix) {
int width = byteMatrix.getWidth();
image = new BufferedImage(width, width,
BufferedImage.TYPE_INT_RGB);
image.createGraphics();
Graphics2D graphics = (Graphics2D) image.getGraphics();
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, width, width);
graphics.setColor(Color.BLACK);
for (int i = 0; i < width; i++) {
for (int j = 0; j < width; j++) {
if (byteMatrix.get(i, j)) {
graphics.fillRect(i, j, 1, 1);
}
}
}
return image;
}
}
我有另一个名为“RepublicaVintageFile”的类,其目的是定义一个唯一的文件来存储我的应用程序的“内容”,并提供一种序列化的方法(和读取,这与问题无关)这个“内容”。这是它的代码:
package ericsonwrp.republica.vintage.caixa;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.util.HashMap;
public class RepublicaVintageFile {
private HashMap<String, Object> content;
public RepublicaVintageFile() {
setContent(new HashMap<String, Object>());
}
public void serializeContent(String path) throws IOException {
FileOutputStream fout = new FileOutputStream(path, true);
ObjectOutput out = null;
try {
out = new ObjectOutputStream(fout);
out.writeObject(getContent());
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException ex) {
// ignore close exception
}
try {
fout.close();
} catch (IOException ex) {
// ignore close exception
}
}
}
public HashMap<String, Object> getContent() {
return content;
}
public void setContent(HashMap<String, Object> content) {
this.content = content;
}
}
我的应用程序的“内容”包括BitMatrix对象,它们保存在HashMap内的标签下的不同文件(private HashMap<String, BitMatrix> qrItems;
)中。由于序列化最终的BufferedImage给了我一个java.io.NotSerializableException
,我试图序列化BitMatrix对象。但是,令我失望的是,这也是不可能的。这是堆栈跟踪:
java.io.NotSerializableException: com.google.zxing.common.BitMatrix
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at java.util.HashMap.internalWriteEntries(Unknown Source)
at java.util.HashMap.writeObject(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at java.util.HashMap.internalWriteEntries(Unknown Source)
at java.util.HashMap.writeObject(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at ericsonwrp.republica.vintage.caixa.RepublicaVintageFile.serializeContent(RepublicaVintageFile.java:26)
at ericsonwrp.republica.vintage.caixa.MainFrame.openSaveAsDialog(MainFrame.java:204)
at ericsonwrp.republica.vintage.caixa.MainFrame.access$1(MainFrame.java:177)
at ericsonwrp.republica.vintage.caixa.MainFrame$4.actionPerformed(MainFrame.java:112)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$500(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
考虑到这一切,我提出了一个问题:如何使用BitMatrix对象序列化HashMap?这很重要,因为我不想在文件夹上存储100个(或更多)单独的.png文件,并且必须一直读取图像以获取其内容。
答案 0 :(得分:0)
我设法“保存”并“加载”BitMatrix对象,将它们转换为布尔的二维数组。
private HashMap<String, BitMatrix> qrMatrixes;
private HashMap<String, boolean[][]> qrMatrixBooleanArrays;
如您所见,我的HashMap为&lt; String,BitMatrix&gt;,具有boolean [] []格式的等价物。这就是我如何进行这种“翻译”(将每个BitMatrix对象的位转移到布尔[] []数组中):
for (Map.Entry<String, BitMatrix> e : getQrMatrixes().entrySet()) {
boolean[][] b = new boolean[e.getValue().getHeight()][e.getValue().getWidth()];
for (int j = 0; j < e.getValue().getHeight(); j++) {
for (int k = 0; k < e.getValue().getWidth(); k++) {
b[j][k] = e.getValue().get(j, k);
}
}
qrMatrixBooleanArrays.put(e.getKey(), b);
}
Java的Serializer序列化这样的对象(HashMap&lt; String,boolean [] []&gt;)没有任何问题,无论它是如何嵌套的(我已经想到它可以使用原始类型,使用老式数组)。以下是加载文件后用QR码更新列表的整个方法:
public void updateList() {
if (MainFrame.getCurrentFile() != null) {
setQrMatrixes(new HashMap<String, BitMatrix>());
setQrMatrixBooleanArrays(new HashMap<String, boolean[][]>());
for (Map.Entry<String, boolean[][]> e : ((HashMap<String, boolean[][]>) MainFrame.getCurrentFile().getContent().get("Qr Codes")).entrySet()) {
getQrMatrixBooleanArrays().put(e.getKey(), e.getValue());
}
for (Map.Entry<String, boolean[][]> e : getQrMatrixBooleanArrays().entrySet()) {
BitMatrix b = new BitMatrix(e.getValue().length, e.getValue().length);
for (int i = 0; i < e.getValue().length; i++) {
for (int j = 0; j < e.getValue()[i].length; j++) {
if (e.getValue()[i][j] == true) {
b.set(i, j);
}
}
}
getQrMatrixes().put(e.getKey(), b);
qrListModel.addElement(e.getKey());
}
} else {
System.out.println("No file is loaded.");
}
}
我担心要更清楚有点难。 Explore the docs用于BitMatrix对象,只需将内容复制到原始的2d数组中。祝你好运!