GIF-файлы (анимации) работают в Appengine, но не на локальном хосте с тем же кодом с помощью blobstore - PullRequest
7 голосов
/ 23 июня 2019

Я использую Blobstore для хранения файлов изображений GIF, которые я затем отображаю в виде тегов HTML <img>. Анимированные GIF-файлы работают нормально при развертывании на работающем экземпляре App Engine, но при развертывании на локальном devserver GIF-файлы перестают быть анимированными.

Я добавил функцию Math.random() в тег изображения, сформированный URL, но он все еще не работал на локальном хосте.

Я ожидал, что анимированные GIF-файлы будут работать на локальном хосте, но моя консоль показывает мне, что плагин ImageIO отсутствует, и средство чтения изображений не найдено, а GIF-файлы не показывают анимацию на локальном хосте.

Здесь - это пример репо, демонстрирующий проблему. Большая часть логики находится в классе 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://stackoverflow.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 не отображается.

Вот вывод в моей командной строке, когда я запускаю devserver и загружаю файл анимированного 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 Ответ

0 голосов
/ 26 июня 2019

Классы java ImageIO по умолчанию могут не иметь необходимого плагина для рендеринга gif-анимации (эти плагины времени выполнения уже будут доступны на серверах GAE | Не в вашей локальной java).Вы должны установить необходимые среды выполнения плагинов.

Например, https://github.com/haraldk/TwelveMonkeys

Или попробуйте это https://imageio.readthedocs.io/en/stable/format_gif-fi.html

Надеюсь, это поможет.

...