Creating and serving an image using AppEngine - image

In Google AppEngine I want to transform a boolean[] into an image then serve the image. I want the boolean[] to be transformed to black and white pixels. I can see that AppEngine provides
import com.google.appengine.api.images.Image;
import com.google.appengine.api.images.ImagesService;
import com.google.appengine.api.images.ImagesServiceFactory;
// ...
byte[] imageData; // ...
ImagesService imagesService = ImagesServiceFactory.getImagesService();
Image image = ImagesServiceFactory.makeImage(imageData);
but I don't know what the format of the byte[] imageData should be, i.e., how to transform the boolean[] to byte[]
And once I have this image, how can the client get it?

The Image service API accepts data in any of the supported image file formats. According to this page, these formats include "JPEG, PNG, WEBP, GIF (including animated GIF), BMP, TIFF and ICO". The Image service does not provide a way to create new image data from scratch. But you can use a graphics library to produce the image in one of the accepted data formats, then use the service to convert it to another format, or transform it. Of course, depending on the graphics library, you may be able to get the final image directly from the library, and not use the service.
To serve an image, just set the appropriate Content-Type header for the data format you're using, then write the bytes of the image data to the response's output stream:
// byte[] pngData = ...
resp.addHeader("Content-Type", "image/png");
resp.getOutputStream().write(pngData);
If you want to try generating the image data without a library, the BMP format might be easiest. You can use the Images service to convert this to PNG.

Related

Convert image to Blob

I want to upload image data to a php script on the server. I have a URL for an image source (PNG, the image might be located on a different server). I load this into a Javascript image, draw this into a canvas and use the canvas.toBlob() method (or a polyfill as it is not mainly supported yet) to generate a blob holding the image data. This works fine, but I recognized that the resulting blob size is much bigger than the original image data.
In contrast if I use a HTML File input and let the user select an image on the client the resulting blob has equal size to the original image. Can I get image data from a canvas that is equal to the original image size?
I guess the reason is that I loose the PNG (or any image compression) when using the canvas.toBlob() polyfill:
value: function (callback, type, quality) {
var binStr = atob(this.toDataURL(type, quality).split(',')[1]),
len = binStr.length,
arr = new Uint8Array(len);
for (var i=0; i<len; i++ ) {
arr[i] = binStr.charCodeAt(i);
}
callback(new Blob([arr], {type: type || 'image/png'}));
}
I am confused by so many conversion steps via image, canvas, blob - so maybe there is an alternative to get the image data from a given URL and finally append it to FormData to send it to the server?
The method toDataURL when using the png format only uses a limited set of the possible formats available for PNG files. It is the 8bit per channel RGBA (32 bits) compressed format. There are no options to use any of the other formats available so you are forced to include redundant data when you save as a PNG. PNG also has a 24bit and 8 bit format. PNG also has several compression options available though I am unsure which is used but each browser.
In most cases it is best to send the original image. If you need to modify the image and do not use the alpha channel (no transparency) but still want the quality to be high send it as a jpeg with quality set to 1 (max).
You may also consider the use of a custom encoder for PNG that gives you access to more of the PNG encoding options, or even try one of the many other formats available, or make up your own format, though you will be hard pushed to improve on jpeg and webp.
You could also consider compressing the data on the server when you store it, even jpeg and webp have a little room for more compression. For transport you should not worry as most data these days is compressed as it leaves the page and most definitely compressed by the time it leaves the clients ISP

App engine image service throws exception with jpeg output image

I am getting an ImagesServiceFailureException exception from the app engine ImagesServiceFactory when specifying JPEG as the output format. It works fine when I specify PNG as the output format. I have only tried this on the app engine development server, not yet on the production server. JPEG is supposed to work according to the app engine docs.
Any idea why this doesn't work? I really don't want to use PNG because of the much greater size images relative to JPEG.
Following is my code:
byte[] sourceData = fetchBlobData(sourceKey);
Image sourceImage = ImagesServiceFactory.makeImage(sourceData);
// Image sourceImage = ImagesServiceFactory.makeImageFromBlob(thumbSourceKey);
ImagesService imagesService = ImagesServiceFactory.getImagesService();
// Create the transform and the new image
Transform resize = ImagesServiceFactory.makeResize(NEW_WIDTH,NEW_HEIGHT);
Image newImage = imagesService.applyTransform(resize, sourceImage, OutputEncoding.JPEG);
When I output as JPEG, I get the following exception:
com.google.appengine.api.images.ImagesServiceFailureException: Failed to encode image
Any help would be greatly appreciated.

how to display a gif image in windows phone 7?

i am trying to load images from facebook. if a user has set a profile picture, then the picture is a jpg, however, if a user has not set one, then the picture is a stub image in gif format. i know that wp7 does not support displaying gif images (out of the box). is there any way to detect if the final picture is a gif or not?
for example, i make a BitmapImage like this:
BitmapImage img = new BitmapImage(new Uri("https://graph.facebook.com/userid1/picture"))
for this uri, the user does not have a profile picture. so i get taken to a stub gif image at https://fbcdn-profile-a.akamaihd.net/static-ak/rsrc.php/v1/yo/r/UlIqmHJn-SK.gif.
if a user does have an image, then i request it as follows.
BitmapImage img = new BitmapImage(new Uri("https://graph.facebook.com/userid2/picture"))
for the above url i get taken to a url like this: https://fbcdn-profile-a.akamaihd.net/hprofile-ak-snc4/000000_1621037713_00000000_q.jpg
my question is then, once i get the BitmapImage object, img, can i determine if this is a JPG or GIF? can i convert it to a JPG if it is a gif?
i looked at some related questions, but the API discussed loaded the image asynchronously, which is not what i wanted at the moment. furthermore, there was poor documentation.
any help is appreciated.
nevermind, i followed the instructions here: Display GIF in a WP7 application with Silverlight. the user gave an excellent walk through.
what you need to do before you do what this user suggested is to download the source code from codeplex.
then you need to download BitMiracle's JPEG library from http://bitmiracle.com/libjpeg/.
go ahead and go into the /src/ImageTools directory and open up ImageTools.Phone.sln. add the ImageTools.IO.Jpeg.Phone project to the solution.
when you build the solution it will complain about not finding BitMiracle's JPEG dll, go ahead and reference that DLL for the Jpeg project. build again, and it should work.
First download the image(any) using Httprequest or Webclient and then convert to jpg or png from gif(if it is gif) in the following way.
GifDecoder gd = new GifDecoder();
ImageTools.ExtendedImage img = new ImageTools.ExtendedImage();
gd.Decode(img, stream); //stream means image stream
PngEncoder png = new PngEncoder();
png.Encode(img, isoFileStreamdownload); //isoFileStreamdownload means stream, which is used to save image in image file like(image.png))
using ImageTools.dll, ImageTools.IO.Gif.dll,ImageTools.IO.Png.dll (Images Tools)
I think it helps to you

What is the Html5 API which retrieves image metadata such as file size, format (jpeg, png ..) from image file?

I want to retrieve metadata (width, hight, format ..) from image file (jpeg, png, bmp etc.) in the Html5.
I can use Canvas Api to deal width image.
However, I cannot find Api to retrieve metadata from a file.
Does anyone can know me?
It looks like this little lib might do the trick for you.

Can jpg images support animation?

jpeg image
How is the above jpg image animated? As far as I know jpg format does not support animation.
No, the JPEG file format has no inherent support for animation.
The image you linked is actually an animated GIF disguised with a jpg file extension. (The browser apparently ignores even the MIME type and looks at the file header bytes in such cases.)
If you view the image in firefox, you can right-click on it and select properties:
You'll see Type: GIF image (animated, 54 frames)
Thus, it is a gif-image that has been renamed to .jpg.
For completeness, I'd like to point our that there's Motion-JPEG - sort of a jpg animation.
MJPEGs, usually produced by webcams, are a stream of JPEG files concatenated together, one after another, sometimes delimited by a HTTP header, and served by webcam-webservers with a MIME-Type of multipart/x-mixed-replace;boundary=, where boundary= defines the delimiter.
A search for animated JPEG related projects on github results in two findings:
In case people care about the size of an animated GIF, they strip it into separate JPG frames and tell the browser to exchange these frames in-place via some JavaScript code. For example. (Pawel's answer)
Then there's actually a proposed Animated JPEG standard, which stems from MJPEG and declares framerate and so forth in each JPG frame. Not probable to arrive in browsers anytime soon.
And lastly, I've seen image-hosters to replace large animated GIFs with a mp4 version of the GIF for presentation, plus some Javascript to serve the actual GIF for downloads/non-supported browsers.
And no, JPEG itself, via JFIF, does not offer a facility to animate a JPG file in itself, just as Noldorin already noted in the chosen answer. :shrug:
It is a GIF image... the extension has been changed by hand. Browser engine is smart enough to determine image format regardless of file extension.
var c = 1;
/* Preloading images */
var image1 = new Image();
image1.src = "a1.jpg";
var image2 = new Image();
image2.src = "a2.jpg";
var image3 = new Image();
image3.src = "a3.jpg";
var image4 = new Image();
image4.src = "a4.jpg";
var image5 = new Image();
image5.src = "a5.jpg";
function disp_img(w)
{
if (c == 6)
{
c = 1;
}
var img_src = "a" + c + ".jpg";
document.ani.src = img_src;
c++;
}
t = setInterval("disp_img(c)", 1000);
No JPEG doesn't support animation. Saving a GIF file with .jpeg extension doesn't male it a JPEG file. It's still a GIF file. Because OS Image viewer doesn't look into file extension it rather looks into the content.
If you open that file as binary (in a text editor) you will see the first line contains
GIF89ad�d�˜|� Which is the magic number for GIF.
Yes,
you can make animation using single jpeg. Google "jpeg css sprites". Of course this will not be native animation support by jpeg format.
A bit of a necro-post but since this question popped first when I tried to get info about pixel motion jpeg, here's some additional info.
Since Pixel2, Google created motion jpeg, which is an ordinary jpeg at the end of which there's an mp4 video.
More on this here:
https://android.jlelse.eu/working-with-motion-photos-da0aa49b50c
JPG does not animate. You either saw a series of JPG images rendered with javascript or you saw a GIF file named as a JPG. A web server and browser might still recognize the correct GIF filetype, even if the wrong extension has been added to the filename.
If you open the image file and if it is a sort of GIF format by using a hex editor, you see the following 4 bytes designating that image type is of GIF.

Resources