首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >imgscalr AsyncScalr的示例代码

imgscalr AsyncScalr的示例代码
EN

Stack Overflow用户
提问于 2012-03-18 03:26:24
回答 2查看 3.1K关注 0票数 3

有人能分享一下使用AsyncScalr调整代码大小的imgscalr的示例代码吗?我正在尝试使用imgscalr (Scalr类)进行图像处理。这是一个很好的且易于使用的库,但是它经常会给OutOfMemoryException带来麻烦。我希望使用AsyncScalr可以解决我的低负载问题。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-03-19 22:14:11

如果您熟悉Java并发库,那么使用AsyncScalr类非常简单;如果您不熟悉新的并发库,那么要点如下:

  1. 调用一个API方法,这个API方法在未来的某个未知点做一些工作;该方法调用返回一个包装实际工作的Future
  2. 最初的API调用实际上是将工作在内部排队;如果它不忙,它可能会立即完成工作,但如果它很忙并且队列很大,可能需要一段时间才能完成工作(在本例中,“
  3. ”是图像的缩放)。
  4. 希望得到结果的调用代码(您的代码)可以继续做工作,直到Future.isDone()返回true指示工作已经完成,或者调用代码可以通过调用以下方法来阻止直到操作完成:Future.get() --此方法返回工作的结果,在本例中,返回表示缩放结果的BufferedImage。

代码从字面上看是这样的:

代码语言:javascript
复制
// Block until result is done
BufferedImage result = AsyncScalr.resize(origImage, 125).get();

这段代码和直接使用Scalr class的不同之处在于,在多线程系统中,如果您从所有线程调用Scalr.resize() (或任何图像操作),每个线程都将启动一个昂贵的图像操作,使您的CPU充满并发工作,并使系统变得缓慢(阻塞在其上运行的其他进程,如DB或web服务器)。

使用AsyncScalr class,您可以从任意数量的线程安全地调用AsyncScalr.resize (或任何其他操作),而不必担心工作会淹没主机系统;AsyncScalr.THREAD_COUNT确定一次可以同时执行多少个作业;您通常希望将此值设置为主机上的核心数或更少-如果主机还托管其他重要的服务,如数据库或web服务器(以确保在伸缩变得繁忙时不会阻塞其他进程)。

您可以在应用程序启动时通过"imgscalr.async.threadCount“系统属性在命令行上设置该线程值;默认情况下,该值为"2",但如果您担心系统内存太少,则可以将其设置为"1”。

或者,如果您在等待结果时有线程可以做的工作,您可以这样做,以便真正充分利用异步编程:

代码语言:javascript
复制
// Queue up the scaling operation (or any other op)
Future<BufferedImage> result = AsyncScalr.resize(origImage, 125);

/*
 * You can do other work here that doesn't need 'result', like making
 * DB calls, cleaning up temp files or anything else you might need to
 * do.
 */

// Now we are all done and need the resulting image, so we wait for it.
BufferedImage scaledImage = result.get();

// Do something with the image...

如果你在等待图像缩放时有大量的其他工作可以做,你可以简单地在result.isDone()上循环并继续工作,直到缩放操作完成;但是如果你只有离散的/特定的工作要做,不需要在isDone上循环,只需完成工作然后调用Future.get()来获得结果(或阻塞,直到它准备好)。

希望这能有所帮助!

票数 3
EN

Stack Overflow用户

发布于 2015-06-29 17:47:27

这是一个实用的方法,用于安排图像的大小调整。这样做的好处是它返回一个ListenableFuture,允许您附加一个回调,该回调将在图像调整大小时执行。

代码语言:javascript
复制
/**
 * Schedules the asynchronous resizing of an image.
 * <p>
 * Uses all available processors to do so.
 * 
 * @param pathToImage
 *            the path to the image we want to resize
 * @param quality
 *            the quality we want the output image to have. One of {@link Method}.
 * @param desiredSize
 *            the resulting image will not have a bigger height or width than this
 * @return
 *         a {@link ListenableFuture} of the resulting image. You can add a callback to it using {@link Futures#addCallback(ListenableFuture, FutureCallback)}
 * @throws IOException
 *             if the image at {@code pathToImage} couldn't be read
 */
public static ListenableFuture<BufferedImage> resize(String pathToImage, Method quality, int desiredSize) throws IOException {

    // Configure AsyncScalr to use all available processors for resizing the images
    String nrOfProcessors = String.valueOf(Runtime.getRuntime().availableProcessors());
    System.setProperty(AsyncScalr.THREAD_COUNT_PROPERTY_NAME, nrOfProcessors);

    BufferedImage image = ImageIO.read(new File(pathToImage));
    Future<BufferedImage> ordinaryFuture = AsyncScalr.resize(image, quality, desiredSize);
    ListenableFuture<BufferedImage> futureImage = JdkFutureAdapters.listenInPoolThread(ordinaryFuture);
    image.flush();
    return futureImage;
}

这就是您如何使用resize

代码语言:javascript
复制
ListenableFuture<BufferedImage> futureImage = resize("/path/to/img.png", Method.SPEED, 250);

Futures.addCallback(futureImage, new FutureCallback<BufferedImage>() {
  @Override
  public void onSuccess(BufferedImage result) {
          System.out.println("Your resized image is ready :-)");
  }
  @Override
  public void onFailure(Throwable t) {
          System.out.println("Couldn't resize image :-(");
  }
});

ListenableFutureFutureCallback都在Guava library中定义。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9753016

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档