Gifs(animations) work on Appengine but not on localhost with the same code by using blobstore
Asked Answered
D

1

6

I'm using Blobstore to store GIF image files, which I then render as HTML <img> tags. Animated GIFs work fine when I deploy to a live instance of App Engine, but when I deploy to a local devserver, the GIFs are no longer animated.

I added Math.random() function in the image tag formed by the url but it still did not work on the local host.

I expected the animated GIF files to work on local host, but my console shows me that ImageIO plugin is missing and image reader is not found and the GIFs do not show animation on the local host.

Here is an example repo that demonstrates the problem. Most of the logic is in the FormHandlerServlet class:

@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://mcmap.net/q/1918982/-restricting-file-type-on-blobstore-upload-in-google-app-engine-java/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);
  }
}

This works for static images, but if I try to upload an animated GIF image, the GIF animation does not show.

Here is the output in my command line when I run a devserver and upload an animated GIF image file:

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
Dipstick answered 23/6, 2019 at 19:38 Comment(0)
B
0

The default ImageIO classes of java might not have the required plugin for rendering gif animations(These runtime plugins will be already available on GAE servers|Not in your local java). You have to install the required plugin runtimes.

For eg., https://github.com/haraldk/TwelveMonkeys

Or try this https://imageio.readthedocs.io/en/stable/format_gif-fi.html

Hope this helps.

Blumenfeld answered 26/6, 2019 at 10:59 Comment(4)
Sorry if I'm misunderstanding something, but the GIF animation is not being rendered by Java, it's being output into HTML. Why would you need a Java library to render the GIF in HTML?Liriodendron
Is it really gif format that comes to UI when you work in local? I suppose the uploaded image does not have GIF capabilities.Blumenfeld
I don't see a GIF plugin listed on these pages. Which dependency should be added to maven?Liriodendron
I followed the instructions on github.com/haraldk/TwelveMonkeys and added the dependencies in pom.xml . The gifs still do not animate on the local serverDipstick

© 2022 - 2024 — McMap. All rights reserved.