使用CUPS pdftoraster生成光栅文件后打印出现格式错误求解决方案
问题描述
我使用cupsfilter的pdftoraster.cxx将PDF文件转换为光栅文件,打印机为Epson L6290,其支持的MIME类型如下:
"application/octet-stream" "image/pwg-raster" "image/urf" "image/jpeg" "application/vnd.epson.escpr"
生成光栅文件的核心代码:
inPdf = fopen("test_raster_0604.tmp","wb"); if(inPdf == NULL){ LOG("pdftoraster() inPdf == NULL"); goto err1; }else{ LOG("pdftoraster() inPdf != NULL"); inpdfdf = fileno(inPdf); } if ((raster = cupsRasterOpen(inpdfdf, pwgraster ? CUPS_RASTER_WRITE_PWG : CUPS_RASTER_WRITE)) == 0) { exit(1); } selectConvertFunc(raster); for (i = 1;i <= npages;i++) { outPage(doc,catalog,i,out,raster); } cupsRasterClose(raster); inSize = ftell(inPdf); //not 0 fclose(inPdf);
随后使用CUPS打印生成的test_raster_0604.tmp文件,核心代码:
int nOptions = 0; File* outRaster = fopen("/data/user/0/cache/test_raster_0604.tmp", "rb"); cupsSetEncryption(HTTP_ENCRYPTION_REQUIRED); cups_dest_t* dest = cupsGetDestWithURI("EPSON_L6290_Series", "ipps://ip_address/ipp/print"); http_t* http = cupsConnectDest(dest, CUPS_DEST_FLAGS_DEVICE, 10000, NULL, resource, sizeof(resource), NULL, NULL); cups_dinfo_t* pInfo = cupsCopyDestInfo(http, dest) nOptions = cupsAddOption(CUPS_COPIES, "1", nOptions, &pOptions); nOptions = cupsAddOption(CUPS_MEDIA, CUPS_MEDIA_A4, nOptions, &pOptions); nOptions = cupsAddOption(CUPS_ORIENTATION, CUPS_ORIENTATION_PORTRAIT, nOptions, &pOptions); ipp_status_t status = cupsCreateDestJob(http, dest, pInfo, &nJobId, "My Document", nOptions, pOptions); if (cupsStartDestDocument(http, dest, pInfo, nJobId, "test_raster_0604.tmp", "image/pwg-raster", 0, NULL, 1) == HTTP_STATUS_CONTINUE) { while ((bytes = fread(buffer, 1, sizeof(buffer), outRaster)) > 0) { if (cupsWriteRequestData(http, buffer, bytes) != HTTP_STATUS_CONTINUE) break; } LOG("Document send write done : %s", cupsLastErrorString()); ///successful-ok if (cupsFinishDestDocument(http, dest, pInfo) != IPP_STATUS_OK) { LOG("Document send failed: %s", cupsLastErrorString()); ///client-error-document-format-error } }
已正确设置MimeType为image/pwg-raster,但CUPS仍返回client-error-document-format-error,求解决方法。
解决排查步骤
1. 确认生成的是标准PWG光栅文件
- 检查代码中
pwgraster变量是否被设为true:代码中cupsRasterOpen的第二个参数依赖该变量,若为false则生成的是CUPS原生光栅格式,而非打印机支持的PWG格式,这是最常见的格式不匹配原因。 - 生成标准对比文件验证:执行
cupsfilter -m image/pwg-raster 你的测试PDF文件 > standard.pwg,然后对比standard.pwg和你生成的test_raster_0604.tmp:- 用
file命令查看文件类型:标准PWG文件应显示image/pwg-raster,若你的文件显示image/cups-raster则说明格式错误。 - 用
hexdump -C查看文件头,对比两者的结构是否一致,PWG光栅有特定的文件头标识。
- 用
2. 匹配光栅文件属性与打印机要求
- 确保生成的光栅文件纸张尺寸、分辨率、色彩模式与打印请求一致:
- 你设置了
CUPS_MEDIA_A4,需确认转换时PDF页面被正确转为A4尺寸,检查outPage函数是否正确处理页面尺寸映射。 - 查询打印机支持的PWG光栅参数:用
ipptool执行属性查询(命令示例:ipptool -tv ipps://你的打印机IP/ipp/print get-printer-attributes.test),查看image/pwg-raster对应的分辨率、色彩空间等属性,确保转换时使用的参数与之匹配。 - 必要时在打印请求中添加分辨率选项:
cupsAddOption(CUPS_RESOLUTION, "600x600", nOptions, &pOptions);,数值需对应打印机支持的参数。
- 你设置了
3. 验证文件发送完整性
- 检查文件读取总字节数是否等于文件实际大小:可以用
stat获取文件大小,对比循环中fread累计的字节数,避免因文件读取不完整导致格式错误。 - 确认
cupsWriteRequestData全程返回HTTP_STATUS_CONTINUE:若中途返回其他状态码,说明发送过程中出现中断,需排查网络连接或打印机状态问题。
4. 命令行打印测试定位问题
- 用CUPS命令行直接打印你的生成文件:
lp -d EPSON_L6290_Series -o media=a4 -o orientation=portrait -m image/pwg-raster test_raster_0604.tmp- 若命令行打印同样报错,说明文件本身格式不符合要求;若命令行打印成功,说明你的API调用遗漏了关键参数,需对比命令行的默认参数与你的代码设置差异。
内容的提问来源于stack exchange,提问作者Jungwon
相关产品推荐
相关产品推荐

