@GET @Path("thumbnails/{slug}_{x: \\d+}_{y: \\d+}_{width: \\d+}_{height: \\d+}.{ext}") public Response downloadThumbnail( @PathParam("slug") String slug, @PathParam("ext") String extension, @PathParam("x") Integer x, @PathParam("y") Integer y, @PathParam("width") Integer width, @PathParam("height") Integer height, @Context ServletContext servletContext, @Context Optional<ImageOptions> imageOptions) { if (!IMAGE_EXTENSIONS.contains(extension)) { // Refuse to treat a request with image options for a non-image attachment return Response.status(Response.Status.BAD_REQUEST).entity("Not an image").build(); } String fileName = slug + "." + extension; Attachment file = this.getAttachmentStore().findBySlugAndExtension(slug, extension); if (file == null) { return Response.status(Response.Status.NOT_FOUND).build(); } try { Image image = imageService.readImage(file.getData()); Rectangle boundaries = new Rectangle(x, y, width, height); RenderedImage cropped = imageService.cropImage(image, boundaries); if (imageOptions.isPresent()) { Optional<Dimension> newDimension = imageService.newDimension( (Image) cropped, imageOptions.get().getWidth(), imageOptions.get().getHeight()); Dimension dimensions = newDimension.or( new Dimension( imageOptions.get().getWidth().get(), imageOptions.get().getHeight().get())); return Response.ok( imageService.scaleImage((Image) cropped, dimensions), servletContext.getMimeType(fileName)) .header("Content-disposition", "inline; filename*=utf-8''" + fileName) .build(); } else { return Response.ok(cropped, servletContext.getMimeType(fileName)) .header("Content-disposition", "inline; filename*=utf-8''" + fileName) .build(); } } catch (IOException e) { this.logger.warn("Failed to scale image for attachment [{slug}]", slug); return Response.serverError().entity("Failed to scale image").build(); } }
@GET @Path("{slug}.{ext}") public Response downloadImage( @PathParam("slug") String slug, @PathParam("ext") String extension, @Context ServletContext servletContext, @Context Optional<ImageOptions> imageOptions) { if (!IMAGE_EXTENSIONS.contains(extension)) { // Refuse to treat a request with image options for a non-image attachment return Response.status(Response.Status.BAD_REQUEST).entity("Not an image").build(); } if (imageOptions.isPresent()) { String fileName = slug + "." + extension; Attachment file = this.getAttachmentStore().findBySlugAndExtension(slug, extension); if (file == null) { return Response.status(Response.Status.NOT_FOUND).build(); } try { Image image = imageService.readImage(file.getData()); if (imageOptions.get().getHeight().isPresent() && imageOptions.get().getWidth().isPresent()) { // Both width and height set -> calculate a fitting box Dimension dimension = new Dimension( imageOptions.get().getWidth().get(), imageOptions.get().getHeight().get()); Optional<Rectangle> fittingBox = imageService.getFittingRectangle(image, dimension); RenderedImage scaled; if (fittingBox.isPresent()) { RenderedImage cropped = imageService.cropImage(image, fittingBox.get()); scaled = imageService.scaleImage((Image) cropped, dimension); } else { scaled = imageService.scaleImage(image, dimension); } return Response.ok(scaled, servletContext.getMimeType(fileName)) .header("Content-disposition", "inline; filename*=utf-8''" + fileName) .build(); } else { Optional<Dimension> newDimension = imageService.newDimension( image, imageOptions.get().getWidth(), imageOptions.get().getHeight()); if (newDimension.isPresent()) { return Response.ok( imageService.scaleImage(image, newDimension.get()), servletContext.getMimeType(fileName)) .header("Content-disposition", "inline; filename*=utf-8''" + fileName) .build(); } return Response.ok(image, servletContext.getMimeType(fileName)) .header("Content-disposition", "inline; filename*=utf-8''" + fileName) .build(); } } catch (IOException e) { this.logger.warn("Failed to scale image for attachment [{slug}]", slug); return Response.serverError().entity("Failed to scale image").build(); } } return this.downloadFile(slug, extension, servletContext); }