Gifs(animations) 可以在 App Engine 上工作,但不能在 localhost 上使用相同的代码通过使用 blob 存储

Posted

技术标签:

【中文标题】Gifs(animations) 可以在 App Engine 上工作,但不能在 localhost 上使用相同的代码通过使用 blob 存储【英文标题】:Gifs(animations) work on Appengine but not on localhost with the same code by using blobstore 【发布时间】:2019-11-05 16:59:54 【问题描述】:

我正在使用 Blobstore 存储 GIF 图像文件,然后将其呈现为 html <img> 标签。当我部署到 App Engine 的实时实例时,动画 GIF 可以正常工作,但是当我部署到本地开发服务器时,GIF 不再是动画的。

我在url形成的图片标签中添加了Math.random()函数,但是在本地主机上还是不行。

我希望动画 GIF 文件可以在本地主机上运行,​​但我的控制台显示 ImageIO 插件丢失并且找不到图像阅读器,并且 GIF 在本地主机上不显示动画。

Here 是一个演示该问题的示例 repo。大部分逻辑都在FormHandlerServlet 类中:

@WebServlet("/my-form-handler")
public class FormHandlerServlet extends HttpServlet 

  @Override
  public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException 

    // Get the message entered by the user.
    String message = request.getParameter("message");

    // Get the URL of the image that the user uploaded to Blobstore.
    String imageUrl = getUploadedFileUrl(request, "image");

    // Output some HTML that shows the data the user entered.
    // A real codebase would probably store these in Datastore.
    ServletOutputStream out = response.getOutputStream();
    out.println("<p>Here's the image you uploaded:</p>");
    out.println("<a href=\"" + imageUrl + "\">");
    out.println("<img src=\"" + imageUrl + "\" />");
    out.println("</a>");
    out.println("<p>Here's the text you entered:</p>");
    out.println(message);
  

  /**
   * Returns a URL that points to the uploaded file, or null if the user didn't upload a file.
   */
  private String getUploadedFileUrl(HttpServletRequest request, String formInputElementName)
    BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
    Map<String, List<BlobKey>> blobs = blobstoreService.getUploads(request);
    List<BlobKey> blobKeys = blobs.get("image");

    // User submitted form without selecting a file, so we can't get a URL. (devserver)
    if(blobKeys == null || blobKeys.isEmpty()) 
      return null;
    

    // Our form only contains a single file input, so get the first index.
    BlobKey blobKey = blobKeys.get(0);

    // User submitted form without selecting a file, so we can't get a URL. (live server)
    BlobInfo blobInfo = new BlobInfoFactory().loadBlobInfo(blobKey);
    if (blobInfo.getSize() == 0) 
      blobstoreService.delete(blobKey);
      return null;
    

    // We could check the validity of the file here, e.g. to make sure it's an image file
    // https://***.com/q/10779564/873165

    // Use ImagesService to get a URL that points to the uploaded file.
    ImagesService imagesService = ImagesServiceFactory.getImagesService();
    ServingUrlOptions options = ServingUrlOptions.Builder.withBlobKey(blobKey);
    return imagesService.getServingUrl(options);
  

这适用于静态图片,但如果我尝试上传 GIF 动画图片,GIF 动画不会显示。

这是我运行开发服务器并上传动画 GIF 图像文件时命令行中的输出:

INFO: Dev App Server is now running

[INFO] Jun 23, 2019 10:41:54 PM com.google.appengine.tools.development.jetty9.LocalResourceFileServlet doGet
[INFO] WARNING: No file found for: /favicon.ico
[INFO] Jun 23, 2019 10:42:04 PM com.google.appengine.api.datastore.dev.LocalDatastoreService init
[INFO] INFO: Local Datastore initialized:
[INFO]  Type: High Replication
[INFO]  Storage: C:\Users\KASHIF YOUSAF\team-42-codeu\target\codeu-starter-project-0.0.1-SNAPSHOT\WEB-INF\appengine-generated\local_db.bin
[INFO] Jun 23, 2019 10:42:05 PM com.google.appengine.api.datastore.dev.LocalDatastoreService load
[INFO] INFO: Time to load datastore: 139 ms
[INFO] Jun 23, 2019 10:42:05 PM com.google.appengine.api.images.dev.LocalImagesService init
[INFO] WARNING: No image reader found for format "ico". An ImageIO plugin must be installed to use this format with the DevAppServer.
[INFO] Jun 23, 2019 10:42:05 PM com.google.appengine.api.images.dev.LocalImagesService init
[INFO] WARNING: No image reader found for format "tif". An ImageIO plugin must be installed to use this format with the DevAppServer.
[INFO] Jun 23, 2019 10:42:05 PM com.google.appengine.api.images.dev.LocalImagesService init
[INFO] WARNING: No image reader found for format "webp". An ImageIO plugin must be installed to use this format with the DevAppServer.
[INFO] Jun 23, 2019 10:42:05 PM com.google.appengine.api.images.dev.LocalImagesService init
[INFO] WARNING: No image writer found for format "webp". An ImageIO plugin must be installed to use this format with the DevAppServer.
[INFO] Jun 23, 2019 10:42:35 PM com.google.appengine.api.datastore.dev.LocalDatastoreService$11 run
[INFO] INFO: Time to persist datastore: 75 ms
[INFO] Jun 23, 2019 10:43:05 PM com.google.appengine.api.datastore.dev.LocalDatastoreService$11 run
[INFO] INFO: Time to persist datastore: 123 ms

【问题讨论】:

【参考方案1】:

java 的默认 ImageIO 类可能没有渲染 gif 动画所需的插件(这些运行时插件将在 GAE 服务器上可用|不在您的本地 java 中)。您必须安装所需的插件运行时。

例如,https://github.com/haraldk/TwelveMonkeys

或者试试这个https://imageio.readthedocs.io/en/stable/format_gif-fi.html

希望这会有所帮助。

【讨论】:

对不起,如果我误解了一些东西,但 GIF 动画不是由 Java 呈现的,而是输出到 HTML 中的。为什么需要 Java 库以 HTML 格式呈现 GIF? 在本地工作时,UI 真的是 gif 格式吗?我想上传的图片没有 GIF 功能。 我没有看到这些页面上列出的 GIF 插件。 maven应该添加哪个依赖? 我按照github.com/haraldk/TwelveMonkeys 上的说明在 pom.xml 中添加了依赖项。 gif 仍然没有在本地服务器上动画

以上是关于Gifs(animations) 可以在 App Engine 上工作,但不能在 localhost 上使用相同的代码通过使用 blob 存储的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 PHP 冻结动画 gifs/转换为 jpg?

php 附加全尺寸gifs.php

用OpenCV创建GIFs,给你的照片戴上墨镜

Flex 3 中的 GIF 动画

如何在uni-app 中使用动画-animation

uni-app引入css动画库