代码如下,正常使用则没有问题,但是添加了线程池就会报错:
com.aspose.pdf.internal.ms.System.l7n: Not supported image type
at com.aspose.pdf.XImage.lI(Unknown Source)
at com.aspose.pdf.XImage.saveInternal(Unknown Source)
at com.aspose.pdf.XImage.saveInternal(Unknown Source)
at com.aspose.pdf.XImage.getImage(Unknown Source)
代码如下:
/**
* 获取PDF文档中的所有图片
*
* @param pdfFilePath PDF文件路径
* @return 图片列表
*/
public static List<BufferedImage> getImages(String pdfFilePath) {
List<BufferedImage> images = new ArrayList<>();
try (Document document = new Document(pdfFilePath)) {
PageCollection pages = document.getPages();
int pageSize = pages.size();
if (pageSize > 5) {
ExecutorService executorService = Executors.newFixedThreadPool(7);
List<Future<List<BufferedImage>>> futures = new ArrayList<>();
for (int i = 1; i <= pageSize; i += 5) {
int endPage = Math.min(i + 4, pageSize);
int finalI = i;
Future<List<BufferedImage>> future = executorService.submit(() -> getImages(pdfFilePath, finalI, endPage));
futures.add(future);
}
for (Future<List<BufferedImage>> future : futures) {
try {
images.addAll(future.get());
} catch (Exception e) {
throw new RuntimeException("获取图片失败", e);
}
}
executorService.shutdown();
} else {
pages.forEach(page -> images.addAll(getImages(page)));
}
return images;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 获取指定页面的所有图片
*
* @param pdfFilePath PDF文件路径
* @param startPageNumber 起始页面索引,从1开始
* @param endPageNumber 结束页面索引,从1开始
* @return 图片列表
*/
public static List<BufferedImage> getImages(String pdfFilePath,
int startPageNumber,
int endPageNumber) {
try (Document document = new Document(pdfFilePath)) {
PageCollection pages = document.getPages();
List<BufferedImage> images = new ArrayList<>();
for (int i = startPageNumber; i <= endPageNumber; i++) {
if (i > pages.size()) {
break;
}
Page page = pages.get_Item(i);
images.addAll(getImages(page));
}
return images;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static List<BufferedImage> getImages(Page page) {
List<BufferedImage> images = new ArrayList<>();
try {
ImagePlacementAbsorber absorber = new ImagePlacementAbsorber();
page.accept(absorber);
for (ImagePlacement imagePlacement : absorber.getImagePlacements()) {
images.add(imagePlacement.getImage().getImage().lf());
}
return images;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
com.aspose.pdf.internal.ms.System.l7n: Not supported image type
at com.aspose.pdf.XImage.lI(Unknown Source)
at com.aspose.pdf.XImage.saveInternal(Unknown Source)
at com.aspose.pdf.XImage.saveInternal(Unknown Source)
at com.aspose.pdf.XImage.getImage(Unknown Source)
at cn.df2680.aihomework.utils.pub.pdf.AsposePdfUtils.getImages(AsposePdfUtils.java:256)
at cn.df2680.aihomework.utils.pub.pdf.AsposePdfUtils.getImages(AsposePdfUtils.java:168)
at cn.df2680.aihomework.utils.pub.pdf.AsposePdfUtils.lambda$getImages$0(AsposePdfUtils.java:225)
at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:840)
com.aspose.pdf.internal.ms.System.l7n: Not supported image type
at com.aspose.pdf.XImage.lI(Unknown Source)
at com.aspose.pdf.XImage.saveInternal(Unknown Source)
at com.aspose.pdf.XImage.saveInternal(Unknown Source)
at com.aspose.pdf.XImage.getImage(Unknown Source)
at cn.df2680.aihomework.utils.pub.pdf.AsposePdfUtils.getImages(AsposePdfUtils.java:220)
at cn.df2680.aihomework.utils.pub.pdf.AsposePdfUtils.lambda$getImages$0(AsposePdfUtils.java:206)
at java.base/java.lang.Iterable.forEach(Iterable.java:75)
at cn.df2680.aihomework.utils.pub.pdf.AsposePdfUtils.getImages(AsposePdfUtils.java:206)
at cn.df2680.aihomework.dddpo.dotmatrix.DotUnitASDownloaderImpl.getPdfImagesWithRetry(DotUnitASDownloaderImpl.java:721)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:351)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:113)
at org.springframework.util.concurrent.FutureUtils.lambda$toSupplier$0(FutureUtils.java:74)
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1768)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:842)
代码:
// 接口
@Async("ioTaskExecutor")
CompletableFuture<List<BufferedImage>> getPdfImages(String pdfPath);
//实现
public CompletableFuture<List<BufferedImage>> getPdfImages(String pdfPath) {
List<BufferedImage> images = AsposePdfUtils.getImages(pdfPath);
return CompletableFuture.completedFuture(images);
}
//工具类实现
public static List<BufferedImage> getImages(String pdfFilePath) {
List<BufferedImage> images = new ArrayList<>();
try (Document document = new Document(pdfFilePath)) {
PageCollection pages = document.getPages();
pages.forEach(page -> images.addAll(getImages(page)));
return images;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static List<BufferedImage> getImages(Page page) {
List<BufferedImage> images = new ArrayList<>();
try {
ImagePlacementAbsorber absorber = new ImagePlacementAbsorber();
page.accept(absorber);
for (ImagePlacement imagePlacement : absorber.getImagePlacements()) {
images.add(imagePlacement.getImage().getImage().lf());
}
return images;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
The code is as follows; this is an asynchronous method annotated with the @Async annotation.
// interface
@Async("ioTaskExecutor")
CompletableFuture<List<BufferedImage>> getPdfImages(String pdfPath);
//impl
public CompletableFuture<List<BufferedImage>> getPdfImages(String pdfPath) {
List<BufferedImage> images = AsposePdfUtils.getImages(pdfPath);
return CompletableFuture.completedFuture(images);
}
//utils
public static List<BufferedImage> getImages(String pdfFilePath) {
List<BufferedImage> images = new ArrayList<>();
try (Document document = new Document(pdfFilePath)) {
PageCollection pages = document.getPages();
pages.forEach(page -> images.addAll(getImages(page)));
return images;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static List<BufferedImage> getImages(Page page) {
List<BufferedImage> images = new ArrayList<>();
try {
ImagePlacementAbsorber absorber = new ImagePlacementAbsorber();
page.accept(absorber);
for (ImagePlacement imagePlacement : absorber.getImagePlacements()) {
images.add(imagePlacement.getImage().getImage().lf());
}
return images;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
Error message as follows:
class com.aspose.pdf.internal.ms.System.l7n: Not supported image type
com.aspose.pdf.XImage.lI(Unknown Source)
com.aspose.pdf.XImage.saveInternal(Unknown Source)
com.aspose.pdf.XImage.saveInternal(Unknown Source)
com.aspose.pdf.XImage.getImage(Unknown Source)
cn.df2680.aihomework.utils.pub.pdf.AsposePdfUtils.lambda$getImagesInParallel$0(AsposePdfUtils.java:263)
java.base/java.lang.Iterable.forEach(Iterable.java:75)
cn.df2680.aihomework.utils.pub.pdf.AsposePdfUtils.lambda$getImagesInParallel$1(AsposePdfUtils.java:258)
java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run$$$capture(CompletableFuture.java:1768)
java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java)
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
java.base/java.lang.Thread.run(Thread.java:840)
at com.aspose.pdf.XImage.lI(Unknown Source)
at com.aspose.pdf.XImage.saveInternal(Unknown Source)
at com.aspose.pdf.XImage.saveInternal(Unknown Source)
at com.aspose.pdf.XImage.getImage(Unknown Source)
at cn.df2680.aihomework.utils.pub.pdf.AsposePdfUtils.lambda$getImagesInParallel$0(AsposePdfUtils.java:263)
at java.base/java.lang.Iterable.forEach(Iterable.java:75)
at cn.df2680.aihomework.utils.pub.pdf.AsposePdfUtils.lambda$getImagesInParallel$1(AsposePdfUtils.java:258)
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run$$$capture(CompletableFuture.java:1768)
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java)
at --- Async.Stack.Trace --- (captured by IntelliJ IDEA debugger)
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.<init>(CompletableFuture.java:1754)
at java.base/java.util.concurrent.CompletableFuture.asyncSupplyStage(CompletableFuture.java:1782)
at java.base/java.util.concurrent.CompletableFuture.supplyAsync(CompletableFuture.java:2005)
at cn.df2680.aihomework.utils.pub.pdf.AsposePdfUtils.getImagesInParallel(AsposePdfUtils.java:253)
at cn.df2680.aihomework.controller.TestController.getImages(TestController.java:538)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:569)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:351)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:765)
at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:58)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:173)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:765)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:89)
at cn.df2680.aihomework.aop.CountTimeAop.around(CountTimeAop.java:30)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:569)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:637)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:627)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:71)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:173)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:765)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:765)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:717)
at cn.df2680.aihomework.controller.TestController$$SpringCGLIB$$0.getImages(<generated>)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:569)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:261)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:189)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:917)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:829)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
at cn.dev33.satoken.filter.SaFirewallCheckFilterForJakartaServlet.doFilter(SaFirewallCheckFilterForJakartaServlet.java:69)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
at cn.dev33.satoken.filter.SaTokenCorsFilterForJakartaServlet.doFilter(SaTokenCorsFilterForJakartaServlet.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
at cn.dev33.satoken.filter.SaTokenContextFilterForJakartaServlet.doFilter(SaTokenContextFilterForJakartaServlet.java:40)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
at org.springframework.web.filter.ServerHttpObservationFilter.doFilterInternal(ServerHttpObservationFilter.java:109)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:340)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1744)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:840)
The error message “Not supported image type” typically indicates that the Aspose library is encountering an image format in the PDF that it cannot process. This can happen for several reasons, especially when working with multithreading.
Cause:
The issue arises when the PDF contains images in unsupported formats or when multithreading is not managed properly, leading to conflicts.
Solution:
Check Image Formats: Ensure that the images in your PDF are in supported formats. Aspose.PDF supports common formats like JPEG, PNG, and BMP. If the PDF contains images in unsupported formats, you will need to handle those cases separately.
Thread Safety: Since you are using multithreading, ensure that each thread is working with its own instance of the Document class. Sharing a single instance across threads can lead to unpredictable behavior and errors.
Error Handling: Enhance your error handling to log the specific image type that is causing the issue. This can help you identify unsupported formats.
Use PdfExtractor: Consider using the PdfExtractor class, which is specifically designed for extracting images and text from PDFs. It may provide better handling for various image types.
Next Steps:
Here’s a modified version of your image extraction logic using PdfExtractor:
public static List<BufferedImage> getImages(String pdfFilePath) {
List<BufferedImage> images = new ArrayList<>();
try (PdfExtractor extractor = new PdfExtractor()) {
extractor.bindPdf(pdfFilePath);
extractor.extractImage();
while (extractor.hasNextImage()) {
BufferedImage image = extractor.getNextImage();
if (image != null) {
images.add(image);
}
}
} catch (Exception e) {
throw new RuntimeException("Error extracting images: " + e.getMessage(), e);
}
return images;
}
This approach ensures that you are using a dedicated extractor for image extraction, which may help avoid the unsupported image type error.
Please implement these suggestions and let me know if you need further assistance!