java - 为什么手动压缩PDF中的图像流后图像会失真?
问题描述
我正在创建一个将图像转换为 PDF 的应用程序。它还具有压缩已创建的 PDF 的功能。这两个功能都在工作。但是在压缩的情况下会出现问题,即PDF文件压缩成功,但压缩后的PDF文件中的大部分图像都变形了。我正在使用 Itext.pdf 库进行转换。我正在粘贴两张图片,第一张图片来自压缩的 PDF,第二张来自压缩的 PDF
我也在粘贴我的代码
// Code for the button, which user Presses to compress a PDF File, I just have chosen a static
file for testing here.
btnCompressPdf.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
File mfile;
mfile = getFilesDir();
farray = mfile.listFiles();
PdfReader reader = new PdfReader(new FileInputStream(farray[0]));
compressReader(reader);
saveReader(reader);
reader.close();
}
catch(FileNotFoundException ex){
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
下面是我在上面的按钮代码中使用的函数代码
private void compressReader(PdfReader reader) throws IOException {
int n = reader.getXrefSize();
PdfObject object;
PRStream stream;
for (int i = 0; i < n; i++) {
object = reader.getPdfObject(i);
if (object == null || !object.isStream())
continue;
stream = (PRStream) object;
compressStream(stream);
}
// code of 'compressStream' function which is called in above function i-e compressReader
private void compressStream(PRStream stream) throws IOException {
PdfObject pdfSubType = stream.get(PdfName.SUBTYPE);
System.out.println(stream.type());
if (pdfSubType != null && pdfSubType.toString().equals(PdfName.IMAGE.toString())) {
PdfImageObject image = new PdfImageObject(stream);
byte[] imageBytes = image.getImageAsBytes();
Bitmap bmp;
bmp = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
if (bmp == null) return;
int width = bmp.getWidth();
int height = bmp.getHeight();
Bitmap outBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas outCanvas = new Canvas(outBitmap);
outCanvas.drawBitmap(bmp, 0f, 0f, null);
ByteArrayOutputStream imgBytes = new ByteArrayOutputStream();
outBitmap.compress(Bitmap.CompressFormat.JPEG, 100, imgBytes);
stream.clear();
stream.setData(imgBytes.toByteArray(), false, PRStream.BEST_COMPRESSION);
stream.put(PdfName.TYPE, PdfName.XOBJECT);
stream.put(PdfName.SUBTYPE, PdfName.IMAGE);
stream.put(PdfName.FILTER, PdfName.DCTDECODE);
stream.put(PdfName.WIDTH, new PdfNumber(width));
stream.put(PdfName.HEIGHT, new PdfNumber(height));
stream.put(PdfName.BITSPERCOMPONENT, new PdfNumber(8));
stream.put(PdfName.COLORSPACE, PdfName.DEVICERGB);
}
}
// code for saveReader Function
private void saveReader(PdfReader reader) throws DocumentException, IOException {
Toast.makeText(MainActivity.this,"inside saveReader",Toast.LENGTH_LONG).show();
FileOutputStream fileOutputStream = openFileOutput("myFileCompressed"+".pdf",
Context.MODE_PRIVATE);
PdfStamper stamper = new PdfStamper(reader, fileOutputStream);
stamper.setFullCompression();
stamper.close();
Toast.makeText(MainActivity.this,"Pdf Created Successfully",Toast.LENGTH_LONG).show();
}
解决方案
推荐阅读
- ios - 如何在 WKWebview 中禁用远程调试?
- flutter - 颤动如何基于空条件创建 TabBarView
- mysql - 如何在 MySQL 中将 GROUP CONCAT 与 COUNT 结合使用?
- android - 如何使用 android-api-service 和 android 应用取消下载过程谷歌驱动器?
- tensorflow - 从没有 numpy 函数的 Tensor 获取 python 字符串
- alert - zabbix 5.X 和 MS 团队集成
- javascript - 使用 Jquery 填充 AngularJS 表单
- node.js - node.js 说找不到 sqlite3 模块
- git - 克隆 GIT 存储库时,Visual Studio“自动”检查出错误的分支
- android - Google Play 商店:由于 Intent 重定向漏洞,Android 应用被拒绝