以下代码片段生成带有文本的 pdf,但图像扭曲像这样
似乎所需的图像应该是
.jpg
。当我使用 .png
时,pdf 中甚至没有显示扭曲的图像。
public static void createPdf() {
try {
//Image image = Image.createImage("/icon.png");
Image image = Image.createImage("/Logo.jpg");
EncodedImage encodedImage = EncodedImage.createFromImage(image, true);
byte[] imageData = encodedImage.getImageData();
StringBuilder content = new StringBuilder();
content.append("%PDF-1.4\n");
content.append("1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj\n");
content.append("2 0 obj<</Type/Pages/Kids [3 0 R]/Count 1>>endobj\n");
content.append("3 0 obj<</Type/Page/Parent 2 0 R/Resources 4 0 R/MediaBox [0 0 520 800]/Contents 6 0 R>>endobj\n");
content.append("4 0 obj<</Font<</F1 5 0 R>>/XObject<</Im0 7 0 R>>>>endobj\n");
content.append("5 0 obj<</Type/Font/Subtype/Type1/BaseFont/Helvetica>>endobj\n");
content.append("6 0 obj<</Length 219>>stream\n");
content.append("BT /F1 24 Tf 175 720 Td (Codename One)Tj ET\n");
content.append("BT /F1 20 Tf 100 700 Td (Using one codebase, build)Tj ET\n");
content.append("BT /F1 20 Tf 0 660 Td (Android apps)Tj ET\n");
content.append("BT /F1 20 Tf 0 640 Td (iOS apps)Tj ET\n");
content.append("BT /F1 20 Tf 0 600 Td (UWP apps)Tj ET\n");
content.append("512 0 0 512 4 50 cm\n");
content.append("/Im0 Do\n");
content.append("endstream\n");
content.append("endobj\n");
content.append("7 0 obj<</Type/XObject/Subtype/Image/Width 512/Height 512/ColorSpace/DeviceRGB/BitsPerComponent 8/Filter/DCTDecode/Length 132959>>stream\n");
content.append(new String(imageData));
content.append("endstream\n");
content.append("endobj\n");
content.append("\n");
content.append("xref\n");
content.append("0 8\n");
content.append("0000000000 65535 f \n");
content.append("0000000009 00000 n \n");
content.append("0000000052 00000 n \n");
content.append("0000000102 00000 n \n");
content.append("0000000197 00000 n \n");
content.append("0000000255 00000 n \n");
content.append("0000000316 00000 n \n");
content.append("0000000609 00000 n \n");
content.append("trailer\n");
content.append("<</Size 8/Root 1 0 R>>\n");
content.append("startxref\n");
content.append("133724\n");
content.append("%%EOF\n");
FileSystemStorage fss = FileSystemStorage.getInstance();
String pdfPath = fss.getAppHomePath() + "Test2.pdf";
try (Writer w = new OutputStreamWriter(fss.openOutputStream(pdfPath))) {
w.write(content.toString());
} catch (Exception e) {
Log.p("Error " + e);
}
} catch (Exception e) {
Log.p("Error " + e);
}
}
生成的pdf保存在应用程序存储目录中
home/.cn1
如何从图像中提取出所需的原始图像数据,使图像能够不失真地显示?
编辑:这个问题与this有点不同,因为我需要生成/创建图像二进制数据并以编程方式而不是手动插入到pdf中
编辑: 下面现在直接写入
InputStream
中的字符。图像流现在更加原始,如this。但图像仍然扭曲,如 this Test6.pdf.
private void createPdf6() {
try {
FileSystemStorage fss = FileSystemStorage.getInstance();
String pdfPath = fss.getAppHomePath() + "Test6.pdf";
try (Writer w = new OutputStreamWriter(fss.openOutputStream(pdfPath))) {
StringBuilder start = new StringBuilder();
start.append("%PDF-1.4\n");
start.append("1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj\n");
start.append("2 0 obj<</Type/Pages/Kids [3 0 R]/Count 1>>endobj\n");
start.append("3 0 obj<</Type/Page/Parent 2 0 R/Resources 4 0 R/MediaBox [0 0 520 800]/Contents 6 0 R>>endobj\n");
start.append("4 0 obj<</Font<</F1 5 0 R>>/XObject<</Im0 7 0 R>>>>endobj\n");
start.append("5 0 obj<</Type/Font/Subtype/Type1/BaseFont/Helvetica>>endobj\n");
start.append("6 0 obj<</Length 219>>stream\n");
start.append("BT /F1 24 Tf 175 720 Td (Codename One)Tj ET\n");
start.append("BT /F1 20 Tf 100 700 Td (Using one codebase, build)Tj ET\n");
start.append("BT /F1 20 Tf 0 660 Td (Android apps)Tj ET\n");
start.append("BT /F1 20 Tf 0 640 Td (iOS apps)Tj ET\n");
start.append("BT /F1 20 Tf 0 600 Td (UWP apps)Tj ET\n");
start.append("512 0 0 512 4 50 cm\n");
start.append("/Im0 Do\n");
start.append("endstream\n");
start.append("endobj\n");
//content.append("7 0 obj<</Type/XObject/Subtype/Image/Width 512/Height 512/ColorSpace/DeviceRGB/BitsPerComponent 8/Filter/DCTDecode/Length 132959>>stream\n");
start.append("7 0 obj<</Type/XObject/Subtype/Image/Width 50/Height 50/ColorSpace/DeviceRGB/BitsPerComponent 8/Length 132959>>stream\n");
w.write(start.toString());
InputStream is = Display.getInstance().getResourceAsStream(this.getClass(), "/Logo.jpg");
//InputStream is = Display.getInstance().getResourceAsStream(this.getClass(), "/icon.jpeg");
//InputStream is = Display.getInstance().getResourceAsStream(this.getClass(), "/icon.png");
int nextChar = is.read();
if (nextChar == -1) {
//return null;
}
while (nextChar > -1) {
//Log.p("Char " + (char) nextChar);
char[] charArray = {(char) nextChar};
w.write(charArray);
nextChar = is.read();
}
StringBuilder end = new StringBuilder();
end.append("\nendstream\n");
end.append("endobj\n");
end.append("\n");
end.append("xref\n");
end.append("0 8\n");
end.append("0000000000 65535 f \n");
end.append("0000000009 00000 n \n");
end.append("0000000052 00000 n \n");
end.append("0000000102 00000 n \n");
end.append("0000000197 00000 n \n");
end.append("0000000255 00000 n \n");
end.append("0000000316 00000 n \n");
end.append("0000000609 00000 n \n");
end.append("trailer\n");
end.append("<</Size 8/Root 1 0 R>>\n");
end.append("startxref\n");
end.append("133724\n");
end.append("%%EOF\n");
w.write(end.toString());
} catch (Exception e) {
Log.p("Error " + e);
}
} catch (Exception e) {
Log.p("Error " + e);
}
}
我必须从对象中删除
Filter/DCTDecode
才能显示图像。为了显示更大的图像,我必须将高度和宽度减小到Width 50/Height 50
。
直接写入 pdf 内容,而不将
StringBuilder
结果附加到 此 Test7.pdf。那就是
private void createPdf7() {
try {
FileSystemStorage fss = FileSystemStorage.getInstance();
String pdfPath = fss.getAppHomePath() + "Test7.pdf";
try (Writer w = new OutputStreamWriter(fss.openOutputStream(pdfPath))) {
w.write("%PDF-1.4\n");
w.write("1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj\n");
w.write("2 0 obj<</Type/Pages/Kids [3 0 R]/Count 1>>endobj\n");
w.write("3 0 obj<</Type/Page/Parent 2 0 R/Resources 4 0 R/MediaBox [0 0 520 800]/Contents 6 0 R>>endobj\n");
w.write("4 0 obj<</Font<</F1 5 0 R>>/XObject<</Im0 7 0 R>>>>endobj\n");
w.write("5 0 obj<</Type/Font/Subtype/Type1/BaseFont/Helvetica>>endobj\n");
w.write("6 0 obj<</Length 219>>stream\n");
w.write("BT /F1 24 Tf 175 720 Td (Codename One)Tj ET\n");
w.write("BT /F1 20 Tf 100 700 Td (Using one codebase, build)Tj ET\n");
w.write("BT /F1 20 Tf 0 660 Td (Android apps)Tj ET\n");
w.write("BT /F1 20 Tf 0 640 Td (iOS apps)Tj ET\n");
w.write("BT /F1 20 Tf 0 600 Td (UWP apps)Tj ET\n");
w.write("512 0 0 512 4 50 cm\n");
w.write("/Im0 Do\n");
w.write("endstream\n");
w.write("endobj\n");
w.write("7 0 obj<</Type/XObject/Subtype/Image/Width 50/Height 50/ColorSpace/DeviceRGB/BitsPerComponent 8/Length 132959>>stream\n");
InputStream is = Display.getInstance().getResourceAsStream(this.getClass(), "/Logo.jpg");
//InputStream is = Display.getInstance().getResourceAsStream(this.getClass(), "/icon.jpeg");
//InputStream is = Display.getInstance().getResourceAsStream(this.getClass(), "/icon.png");
int nextChar = is.read();
if (nextChar == -1) {
//return null;
}
while (nextChar > -1) {
//Log.p("Char " + (char) nextChar);
char[] charArray = {(char) nextChar};
w.write(charArray);
nextChar = is.read();
}
w.write("\nendstream\n");
w.write("endobj\n");
w.write("\n");
w.write("xref\n");
w.write("0 8\n");
w.write("0000000000 65535 f \n");
w.write("0000000009 00000 n \n");
w.write("0000000052 00000 n \n");
w.write("0000000102 00000 n \n");
w.write("0000000197 00000 n \n");
w.write("0000000255 00000 n \n");
w.write("0000000316 00000 n \n");
w.write("0000000609 00000 n \n");
w.write("trailer\n");
w.write("<</Size 8/Root 1 0 R>>\n");
w.write("startxref\n");
w.write("133724\n");
w.write("%%EOF\n");
} catch (Exception e) {
Log.p("Error " + e);
}
} catch (Exception e) {
Log.p("Error " + e);
}
}
为了使图像正确显示,我还缺少什么?
编辑 使用 Linux 文本编辑器打开 this JSjpegSample-with image.pdf 显示以下图像数据流编码。注意一些可读的文字,例如
JFIF
Photoshop 7.0
在 Codename One 模拟器中,这种编码方式与 SQLite 数据库文件的编码方式接近。使用 Linux 文本编辑器打开 SQLite 数据库显示以下内容。注意一些可读的文字,例如
SQLite format 3
CREATE TABLE
如何将要添加到 pdf 的
.jpeg
以与 SQLite 数据库文件相同的方式编码?
以下成功将图像添加到pdf文档中。要求包括:
使用以下命令创建
jpeg
图像
EncodedImage.createFromImage(image, true);
这很有用,因为 png
图像可以转换为 jpeg
从图像字节创建
ByteArrayInputStream
。使用 ByteArrayInputStream
,图像字节直接作为字符写入 pdf。
在
ISO-8859-1
中设置OutputStreamWriter
编码。这种编码确保图像字节中的所有字符都按预期读取 Filter/DCTDecode
。
Windows-1252
编码也尝试,但一些十六进制被读取为?
。
private void createPdf11() {
try {
Image image = Image.createImage("/Logo.jpg");
//Image image = Image.createImage("/icon.jpeg");
//Image image = Image.createImage("/icon.png");
//create a jpeg encoded image
EncodedImage encodedImage = EncodedImage.createFromImage(image, true);
byte[] imageData = encodedImage.getImageData();
//create ByteArrayInputStream from image byte array
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(imageData);
FileSystemStorage fss = FileSystemStorage.getInstance();
String pdfPath = fss.getAppHomePath() + "Test11.pdf";
try (Writer w = new OutputStreamWriter(fss.openOutputStream(pdfPath), "ISO-8859-1")) {
w.write("%PDF-1.7\n");
w.write("1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj\n");
w.write("2 0 obj<</Type/Pages/Kids [3 0 R]/Count 1>>endobj\n");
w.write("3 0 obj<</Type/Page/Parent 2 0 R/Resources 4 0 R/MediaBox [0 0 520 800]/Contents 6 0 R>>endobj\n");
w.write("4 0 obj<</Font<</F1 5 0 R>>/XObject<</Im0 7 0 R>>>>endobj\n");
w.write("5 0 obj<</Type/Font/Subtype/Type1/BaseFont/Helvetica>>endobj\n");
w.write("6 0 obj<</Length 219>>stream\n");
w.write("BT /F1 24 Tf 175 720 Td (Codename One)Tj ET\n");
w.write("BT /F1 20 Tf 100 700 Td (Using one codebase, build)Tj ET\n");
w.write("BT /F1 20 Tf 0 660 Td (Android apps)Tj ET\n");
w.write("BT /F1 20 Tf 0 640 Td (iOS apps)Tj ET\n");
w.write("BT /F1 20 Tf 0 600 Td (UWP apps)Tj ET\n");
w.write("512 0 0 512 4 50 cm\n");
w.write("/Im0 Do\n");
w.write("endstream\n");
w.write("endobj\n");
w.write("7 0 obj<</Type/XObject/Subtype/Image/Width 512/Height 512/ColorSpace/DeviceRGB/BitsPerComponent 8/Filter/DCTDecode/Length 132959>>stream\n");
//read the next byte of data from ByteArrayInputStream in int range 0 - 255
int nextChar = byteArrayInputStream.read();
while (nextChar > -1) {
//convert int to char and add it to char array
char[] charArray = {(char) nextChar};
//write char array
w.write(charArray);
nextChar = byteArrayInputStream.read();
}
w.write("\nendstream\n");
w.write("endobj\n");
w.write("\n");
w.write("xref\n");
w.write("0 8\n");
w.write("0000000000 65535 f \n");
w.write("0000000009 00000 n \n");
w.write("0000000052 00000 n \n");
w.write("0000000102 00000 n \n");
w.write("0000000197 00000 n \n");
w.write("0000000255 00000 n \n");
w.write("0000000316 00000 n \n");
w.write("0000000609 00000 n \n");
w.write("trailer\n");
w.write("<</Size 8/Root 1 0 R>>\n");
w.write("startxref\n");
w.write("133724\n");
w.write("%%EOF\n");
} catch (Exception e) {
Log.p("Error " + e);
}
} catch (Exception e) {
Log.p("Error " + e);
}
}
这将在应用程序主路径目录中创建带有文本和图像的 Test11.pdf
home/.cn1