27798

Appengine conversion Api (java)

Question:

I want to convert pdfs to image files within appengine. Ideally I would upload the pdf as a blob and store both the pdf and an image of the pdf. The conversion could also be done at a different time (taskqueue).

I have not found any working samples or good documentation of doing this.<br /> The official documentation is <a href="https://developers.google.com/appengine/docs/java/conversion/overview" rel="nofollow">here</a>. Here is my implementation on my upload servlet.

@SuppressWarnings("serial") public class UploadBlobServlet extends HttpServlet { private static final Logger log = Logger.getLogger(UploadBlobServlet.class.getName()); public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService(); Map<String, BlobKey> blobs = blobstoreService.getUploadedBlobs(req); BlobKey blobKey = blobs.get("data"); log.log(Level.WARNING,"blobKey: "+blobKey.getKeyString()); if (blobKey != null) { resp.getWriter().println(blobKey.getKeyString()); BlobstoreInputStream in=new BlobstoreInputStream(blobKey); byte[] b = IOUtils.toByteArray(is); // try{ in.read(b); Asset asset = new Asset( "application/pdf", b, "testfile.pdf"); Document document = new Document(asset); Conversion conversion = new Conversion(document, "image/png"); ConversionService service = ConversionServiceFactory.getConversionService(); ConversionResult result = service.convert(conversion); if (result.success()) { // Note: in most cases, we will return data all in one asset, // except that we return multiple assets for multi-page images. FileService fileService=FileServiceFactory.getFileService(); for (Asset ass : result.getOutputDoc().getAssets()) { AppEngineFile file=fileService.createNewBlobFile("image/png", "testfile.png"); FileWriteChannel writeChannel=fileService.openWriteChannel(file, false); writeChannel.write(ByteBuffer.wrap(b)); writeChannel.closeFinally(); } } else { log.log(Level.WARNING,"error"); }

Update: Have added byte[]=IOUtils.toByteArray(is); and still getting a NPE...

I am also curious as to the quality of the conversion if anyone has experience.

Answer1:

To convert a document you first have to create an asset. An asset is created by passing the the bytes to the constructor, as shown in the example. In your case you will need to use class <a href="https://developers.google.com/appengine/docs/java/javadoc/com/google/appengine/api/blobstore/BlobstoreInputStream" rel="nofollow">BlobstoreInputStream</a> to read the bytes of your PDF.

BlobKey blobKey = new BlobKey("your-pdf-blobkey"); InputStream is = new BlobstoreInputStream(blobkey);

Then you need to read all bytes from this input stream.

After the conversion, you can access the bytes of the converted image with asset.getData() and then follow <a href="https://developers.google.com/appengine/docs/java/blobstore/overview#Writing_Files_to_the_Blobstore" rel="nofollow">this doc</a> to write the image to the blobstore.

Answer2:

Here is the working code to receive an upload pdf and convert it to a png using the Conversion api. The upload is completed with a multi-part post to an upload url must be obtained through:

String url=blobstoreService.createUploadUrl("/upload");

Just place this code in a servlet and map it to "upload" in your web.xml.

The Conversion is good quality, however I did notice just a little blurriness around text. In my case the png was about 25% larger.

public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService(); Map<String, BlobKey> blobs = blobstoreService.getUploadedBlobs(req); BlobKey blobKey = blobs.get("data"); if (blobKey != null) { resp.getWriter().println(blobKey.getKeyString()); BlobstoreInputStream in=new BlobstoreInputStream(blobKey); byte[] b = IOUtils.toByteArray(in); if(b!=null){ log.log(Level.WARNING,"blobsize: "+b.length); }else{ log.log(Level.WARNING,"b is null"); } in.read(b); Asset asset = new Asset( "application/pdf", b, "testfile.pdf"); Document document = new Document(asset); Conversion conversion = new Conversion(document, "image/png"); ConversionService service = ConversionServiceFactory.getConversionService(); ConversionResult result = service.convert(conversion); if (result.success()) { // Note: in most cases, we will return data all in one asset, // except that we return multiple assets for multi-page images. FileService fileService=FileServiceFactory.getFileService(); for (Asset ass : result.getOutputDoc().getAssets()) { AppEngineFile file=fileService.createNewBlobFile("image/png", "test3file.png"); FileWriteChannel writeChannel=fileService.openWriteChannel(file, true); writeChannel.write(ByteBuffer.wrap(ass.getData())); writeChannel.closeFinally(); } } else { log.log(Level.WARNING,"error"); }

Recommend

  • Expected BlobKey but instead I get a BlobInfo object - How to get BlobKey from BlobInfo object?
  • How to display images on html page from python/jinja
  • What would be the best way to send NSData through PHP into MySQL?
  • Store tiff images in SQL Server or file system?
  • Save documents as BLOB in SQL or on file system
  • what is call to function $openid->validate do?
  • Why use .takeUntil() over .take(1) with Http service?
  • C: Incompatible pointer type initializing
  • How reduce the height of an mschart by breaking up the y-axis
  • How to add date and time under each post in guestbook in google app engine
  • SSO with signing and signature validation doesn't work
  • How to show dropdown in excel using jrxml (jasper api)?
  • Redux, normalised entities and lodash merge
  • Importing jscolor library in angular 2
  • Release, debug version and Authorization Google?
  • Websockets service method fails during R startup
  • Alternatives to the OPTIONAL fallback SPARQL pattern?
  • How to get next/previous record number?
  • Function pointer “assignment from incompatible pointer type” only when using vararg ellipsis
  • Apache 2.4 - remove | delete | uninstall
  • AT Commands to Send SMS not working in Windows 8.1
  • Run Powershell script from inside other Powershell script with dynamic redirection to file
  • Windows forms listbox.selecteditem displaying “System.Data.DataRowView” instead of actual value
  • Android Studio and gradle
  • Proper way to use connect-multiparty with express.js?
  • Trying to get generic when generic is not available
  • embed rChart in Markdown
  • How to get Windows thread pool to call class member function?
  • IndexOutOfRangeException on multidimensional array despite using GetLength check
  • apache spark aggregate function using min value
  • Sorting a 2D array using the second column C++
  • How to get NHibernate ISession to cache entity not retrieved by primary key
  • costura.fody for a dll that references another dll
  • Observable and ngFor in Angular 2
  • How to Embed XSL into XML
  • How can I use `wmic` in a Windows PE script?
  • UserPrincipal.Current returns apppool on IIS
  • Unable to use reactive element in my shiny app
  • Conditional In-Line CSS for IE and Others?
  • java string with new operator and a literal