How to use imgscalr using Grails - image

I've just begun using Groovy and Grails the last few days. I don't have any prior experience of Java, so you'll have to excuse this (probably) very basic question. I've searched Google and Stack Overflow and haven't found anything that helps me with the actually installation.
I have got an image upload working, and I am storing the file on the server. I used a IBM Grails tutorial to guide me through it. That works fine.
I would also like to resize the file in a large, medium, and small format. I wanted to use imgscalr for this, but I cant get it to work. I have downloaded version 4.2 which contains various .jar files. Do I need to put these somewhere on the server and reference them? The only thing I've done is add these lines to buildConfig.groovy
dependencies {
// specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.
// runtime 'mysql:mysql-connector-java:5.1.20'
compile 'org.imgscalr:imgscalr-lib:4.2'
}
and import org.imgscalr.Scalr.* in my PhotoController.Groovy
Here's my code for saving the file onto the server, I would also like to resize and save the image.
def save() {
def photoInstance = new Photo(params)
// Handle uploaded file
def uploadedFile = request.getFile('photoFile')
if(!uploadedFile.empty) {
println "Class: ${uploadedFile.class}"
println "Name: ${uploadedFile.name}"
println "OriginalFileName: ${uploadedFile.originalFilename}"
println "Size: ${uploadedFile.size}"
println "ContentType: ${uploadedFile.contentType}"
def webRootDir = servletContext.getRealPath("/")
def originalPhotoDir = new File(webRootDir, "/images/photographs/original")
originalPhotoDir.mkdirs()
uploadedFile.transferTo(new File(originalPhotoDir, uploadedFile.originalFilename))
BufferedImage largeImg = Scalr.resize(uploadedFile, 1366);
def largePhotoDir = new File(webRootDir, "/images/photographs/large")
largePhotoDir.mkdirs()
photoInstance.photoFile = uploadedFile.originalFilename
}
if (!photoInstance.hasErrors() && photoInstance.save()) {
flash.message = "Photo ${photoInstance.id} created"
redirect(action:"list")
}
else {
render(view:"create", model:[photoInstance: photoInstance])
}
}
The error I'm getting is No such property: Scalr for class: garethlewisweb.PhotoController
I'm obviously doing something very wrong. Any guidance appreciated.

This is the first google result for "How to use imgscalr in grails" and I was surprised with the lack of informations and examples when googling it. Although the first answer is close, there's still a few mistakes to be corrected.
To anyone that ended here like me through google, heres a more detailed example of how to correctly use this nice plugin:
First, declare the plugin in your BuildConfig.groovy file:
dependencies {
// specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.
// runtime 'mysql:mysql-connector-java:5.1.20'
compile 'org.imgscalr:imgscalr-lib:4.2'
}
Then, after installed, just paste this piece of code in your controller, in the action that receives the multi-part form with the image uploaded.
def create() {
def userInstance = new User(params)
//saving image
def imgFile = request.getFile('myFile')
def webRootDir = servletContext.getRealPath("/")
userInstance.storeImageInFileSystem(imgFile, webRootDir)
(...)
}
Inside my domain, I implemented this storeImageInFileSystem method, that will resize the image and store it in the filesystem. But first, import this to the file:
import org.imgscalr.Scalr
import java.awt.image.BufferedImage
import javax.imageio.ImageIO
And then, implement the method:
def storeImageInFileSystem(imgFile, webRootDir){
if (!imgFile.empty)
{
def defaultPath = "/images/userImages"
def systemDir = new File(webRootDir, defaultPath)
if (!systemDir.exists()) {
systemDir.mkdirs()
}
def imgFileDir = new File( systemDir, imgFile.originalFilename)
imgFile.transferTo( imgFileDir )
def imageIn = ImageIO.read(imgFileDir);
BufferedImage scaledImage = Scalr.resize(imageIn, 200); //200 is the size of the image
ImageIO.write(scaledImage, "jpg", new File( systemDir, imgFile.originalFilename )); //write image in filesystem
(...)
}
}
This worked well for me. Change any details as the need, like the system diretory or the size of the image.

Instead of
import org.imgscalr.Scalr.*
You want
import org.imgscalr.Scalr
import javax.imageio.ImageIO
Then resize needs a BufferedImage (looking at the JavaDocs), so try:
def originalPhotoDir = new File(webRootDir, "/images/photographs/original")
originalPhotoDir.mkdirs()
def originalPhotoFile = new File(originalPhotoDir, uploadedFile.originalFilename)
uploadedFile.transferTo( originalPhotoFile )
// Load the image
BufferedImage originalImage = ImageIO.read( originalPhotoFile )
// Scale it
BufferedImage largeImg = Scalr.resize(uploadedFile, 1366);
// Make the destination folder
def largePhotoDir = new File(webRootDir, "/images/photographs/large" )
largePhotoDir.mkdirs()
// Write the large image out
ImageIO.write( largeImg, 'png', new File( largePhotoDir, uploadedFile.originalFilename )
Of course, you'll have to watch for files overwriting already existing images

Put the jar file(s) in the 'lib' directory of your Grails application. You may then delete that line from BuildConfig.groovy

Related

How to test ImagePicker in Flutter Driver?

In Flutter integration testing, how can we handle ImagePicker? as well as other platform related plugins?
Finally, I got a solution for this question.
this is the code in app.dart:
prepare an image file in assets, for example: images/sample.png.
import 'dart:io';
import 'dart:typed_data';
import 'package:path_provider/path_provider.dart';
import 'package:image_picker_test/main.dart' as app;
import 'package:flutter_driver/driver_extension.dart';
import 'package:flutter/services.dart';
void main() {
// This line enables the extension.
enableFlutterDriverExtension();
const MethodChannel channel =
MethodChannel('plugins.flutter.io/image_picker');
channel.setMockMethodCallHandler((MethodCall methodCall) async {
ByteData data = await rootBundle.load('images/sample.png');
Uint8List bytes = data.buffer.asUint8List();
Directory tempDir = await getTemporaryDirectory();
File file = await File('${tempDir.path}/tmp.tmp', ).writeAsBytes(bytes);
print(file.path);
return file.path;
});
app.main();
}
Frank Yan's solution works fine. Basically he is using MethodChannel as an interceptor of request to ImagePicker
MethodChannel('plugins.flutter.io/image_picker')
In this part he defines which plugin has to be mocked
channel.setMockMethodCallHandler((MethodCall methodCall) async {
ByteData data = await rootBundle.load('images/sample.png');
Uint8List bytes = data.buffer.asUint8List();
Directory tempDir = await getTemporaryDirectory();
File file = await File('${tempDir.path}/tmp.tmp', ).writeAsBytes(bytes);
print(file.path);
return file.path;
});
This function defines what has to be returned from request to image picker plugin. So your program will do these actions each time when user uses image picker. Right here it will just return the image from 'images/sample.png'. In my case I had to put image into assets/image.png in my project root. Anyway you can mock any plugin like that. I had to also mock cropper plugin which is called after image picker ends it's job.
**Note: **mocking is not the best way to go with e2e or as they are called in flutter integration tests. I used it just because there is no workaround (I couldn't find it) at the moment and I am blocked with step of picture upload in my scenario. So be careful with using such approach.
You don't need to call this function anywhere in test. Your app will run with mocked plugin that we define in MethodChannel constuctor MethodChannel('');

Dynamics CRM Attachment Data Import Using SDK

I am trying to import Attachments/Annotations to CRM Dynamics, I am doing this using the SDK.
I am not using the data import wizard.
I am not individually creating Annotation entities, instead I am using Data Import Feature programmatically.
I mostly leveraged the DataImport sample from the SDK sample code (SDK\SampleCode\CS\DataManagement\DataImport).
Import import = new Import()
{
ModeCode = new OptionSetValue((int)ImportModeCode.Create),
Name = "Data Import"
};
Guid importId = _serviceProxy.Create(import);
_serviceProxy.Create(
new ColumnMapping()
{
ImportMapId = new EntityReference(ImportMap.EntityLogicalName, importMapId),
ProcessCode = new OptionSetValue((int)ColumnMappingProcessCode.Process),
SourceEntityName = sourceEntityName,
SourceAttributeName = sourceAttributeName,
TargetEntityName = targetEntityName,
TargetAttributeName = targetAttributeName
});
I am getting an error "The reference to the attachment could not be found".
The documentation says the crm async service will find the physical file on disk and upload it, my question is where does the async service look for attachment files?
I tried to map documentbody field to the full path of the attachment on the desk, but that still didn't work.
The answer below was provided before the question edits clarifying the use of the import wizard instead of the SDK. The answer below is specific to using the SDK.
When you are attaching files to an Annotation (Note) record in CRM via the SDK, you do use the documentbody attribute (along with mimetype), but you have to first convert it base64.
Something like this:
var myFile = #"C:\Path\To\My\File.pdf";
// Do checks to make sure file exists...
// Convert to Base64.
var base64Data = Convert.ToBase64String(System.IO.File.ReadAllBytes(myFile));
var newNote = new Entity("annotation");
// Set subject, regarding object, etc.
// Add the data required for a file attachment.
newNote.Attributes.Add("documentbody", base64Data);
newNote.Attributes.Add("mimetype", "text/plain"); // This mime type seems to work for all file types.
orgService.Create(newNote);
I found the solution in an obscure blog post, I think the documentation is misleading or unclear, the way this whole thing works, makes having the files available on the server disk for the async to process, odd.
To follow the same principle, all contents should be sent like the csv file itself while being linked to the same import.
To solve this we need create individual special Internal ImportFile for each physical attachment, and link it to the import that has the attachments record details.
As you see below with linking the attachments ImportFile using the ImportId and then setting the two properties (ProcessCode and FileTypeCode), it all worked in the end.
Suffice to say using this method is much more efficient and quicker than individually creating Annotation records.
foreach (var line in File.ReadLines(csvFilesPath + "Attachment.csv").Skip(1))
{
var fileName = line.Split(',')[0].Replace("\"", null);
using (FileStream stream = File.OpenRead(attachmentsPath + fileName))
{
byte[] byteData = new byte[stream.Length];
stream.Read(byteData, 0, byteData.Length);
stream.Close();
string encodedAttachmentData = System.Convert.ToBase64String(byteData);
ImportFile importFileAttachment = new ImportFile()
{
Content = encodedAttachmentData,
Name = fileName,
ImportMapId = new EntityReference(ImportMap.EntityLogicalName, importMapId),
UseSystemMap = true,
ImportId = new EntityReference(Import.EntityLogicalName, importId),
ProcessCode = new OptionSetValue((int)ImportFileProcessCode.Internal),
FileTypeCode = new OptionSetValue((int)ImportFileFileTypeCode.Attachment),
RecordsOwnerId = currentUserRef
};
_serviceProxy.Create(importFileAttachment);
}
idx++;
}

Why is the toolbar not visible in executable Jar created using IntelliJ?

I have created a jar file for my GUI application using IntelliJ. However, when I run the file, I cannot see the toolbar which contains the buttons with ImageIcon for different functionaltites. On looking around over stackoverflow (like here: Java Swing ImageIcon, where to put images?), I found that the file path for the images could be an issue. At present I am using the following code:
OpenImagingFileButton = new JButton(createImageIcon(currentPath.concat("/src/main/java/uni/images/open-file-icon-img.png")));
The currentPath variable is obtained using this:
final String currentPath = currentRelativePath.toAbsolutePath().toString();
And the createImageIcon method has the following code:
/**
* Returns an ImageIcon, or null if the path was invalid.
*/
protected static ImageIcon createImageIcon(String path) {
ImageIcon toolBarImage = new ImageIcon(path);
Image image = toolBarImage.getImage(); // transform it
Image newImg = image.getScaledInstance(20, 20, java.awt.Image.SCALE_SMOOTH); // scale it the smooth way
toolBarImage = new ImageIcon(newImg); // transform it back
return toolBarImage;
}
This code works perfectly when I run it in intelliJ, however, the toolbar is not visible when I run the jar. I also tried moving the images folder directly under src folder and then doing this:
ImageIcon(this.getClass().getResource("/images/open-file-icon-img.png"));
But this gives me aNullPointerException. Where am I going wrong?
You don’t need to use the current path here. Since you are working in IntelliJ, simply mark the folder as resources root, by selecting the src folder and right clicking it to find
mark directory as
Move the images folder under the src folder. Then use the following code to set the image icon as a button
Java - setting classpath
openProject = new JButton();
openProject.setIcon(createToolIcon("/images/openProject.png"));
And place the createToolIcon method in the same class file or create a separate class and call the method using that class.
public static ImageIcon createToolIcon(String path) {
URL url = System.class.getResource(path);
if(url == null) {
System.err.println("Unable to load Image: " + path);
}
ImageIcon icon = new ImageIcon(url);
Image img = icon.getImage();
Image newimg = img.getScaledInstance(20, 20, java.awt.Image.SCALE_SMOOTH)
ImageIcon newIcon = new ImageIcon(newimg);
return newIcon;
}

PDF Box generating blank images due to JBIG2 Images in it

Let me give you an overview of my project first. I have a pdf which I need to convert into images(One image for one page) using PDFBox API and write all those images onto a new pdf using PDFBox API itself. Basically, converting a pdf into a pdf, which we refer to as PDF Transcoding.
For certain pdfs, which contain JBIG2 images, PDFbox implementation of convertToImage() method is failing silently without any exceptions or errors and finally, producing a PDF, but this time, just with blank content(white). The message I am getting on the console is:
Dec 06, 2013 5:15:42 PM org.apache.pdfbox.filter.JBIG2Filter decode
SEVERE: Can't find an ImageIO plugin to decode the JBIG2 encoded datastream.
Dec 06, 2013 5:15:42 PM org.apache.pdfbox.pdmodel.graphics.xobject.PDPixelMap getRGBImage
SEVERE: Something went wrong ... the pixelmap doesn't contain any data.
Dec 06, 2013 5:15:42 PM org.apache.pdfbox.util.operator.pagedrawer.Invoke process
WARNING: getRGBImage returned NULL
I need to know how to resolve this issue? We have something like:
import org.apache.pdfbox.filter.JBIG2Filter;
which I don't know how to implement.
I am searching on that, but to no avail. Could anyone please suggest?
Take a look at this ticket in PDFBox https://issues.apache.org/jira/browse/PDFBOX-1067 . I think the answer to your question is:
to make sure that you have JAI and the JAI-ImageIO plugins installed for your version of Java: decent installation instructions are available here: http://docs.geoserver.org/latest/en/user/production/java.html
to use the JBIG2-imageio plugin, (newer versions are licensed under the Apache2 license) https://github.com/levigo/jbig2-imageio/
I had the same problem and I fixed it by adding this dependency in my pom.xml :
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>jbig2-imageio</artifactId>
<version>3.0.2</version>
</dependency>
Good luck.
I had the exact same problem.
I downloaded the jar from
jbig2-imageio
and I just included it in my project's application libraries, and it worked right out of the box. As adam said, it uses GPL3.
Installing the JAI seems not needed.
I only needed to download the levigo-jbig2-imageio-1.6.5.jar, place it in the folder of my dependency-jars and in eclipse add it to the java build path libraries.
https://github.com/levigo/jbig2-imageio/
import java.awt.image.BufferedImage
import org.apache.pdfbox.cos.COSName
import org.apache.pdfbox.pdmodel.PDDocument
import org.apache.pdfbox.pdmodel.PDPage
import org.apache.pdfbox.pdmodel.PDPageTree
import org.apache.pdfbox.pdmodel.PDResources
import org.apache.pdfbox.pdmodel.graphics.PDXObject
import org.apache.pdfbox.rendering.ImageType
import org.apache.pdfbox.rendering.PDFRenderer
import org.apache.pdfbox.tools.imageio.ImageIOUtil
import javax.imageio.ImageIO
import javax.imageio.spi.IIORegistry
import javax.imageio.spi.ImageReaderSpi
import javax.swing.*
import javax.swing.filechooser.FileNameExtensionFilter
public class savePDFAsImage{
String path = "c:/pdfImage/"
//allow pdf file selection for extracting
public static File selectPDF() {
File file = null
JFileChooser chooser = new JFileChooser()
FileNameExtensionFilter filter = new FileNameExtensionFilter("PDF", "pdf")
chooser.setFileFilter(filter)
chooser.setMultiSelectionEnabled(false)
int returnVal = chooser.showOpenDialog(null)
if (returnVal == JFileChooser.APPROVE_OPTION) {
file = chooser.getSelectedFile()
println "Please wait..."
}
return file
}
public static void main(String[] args) {
try {
// help to view list of plugin registered. check by adding JBig2 plugin and JAI plugin
ImageIO.scanForPlugins()
IIORegistry reg = IIORegistry.getDefaultInstance()
Iterator spIt = reg.getServiceProviders(ImageReaderSpi.class, false)
spIt.each(){
println it.getProperties()
}
testPDFBoxSaveAsImage()
testPDFBoxExtractImagesX()
} catch (Exception e) {
e.printStackTrace()
}
}
public static void testPDFBoxExtractImagesX() throws Exception {
PDDocument document = PDDocument.load(selectPDF())
PDPageTree list = document.getPages()
for (PDPage page : list) {
PDResources pdResources = page.getResources()
for (COSName c : pdResources.getXObjectNames()) {
PDXObject o = pdResources.getXObject(c)
if (o instanceof org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject) {
File file = new File( + System.nanoTime() + ".png")
ImageIO.write(((org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject) o).getImage(), "png", file)
}
}
}
document.close()
println "Extraction complete"
}
public static void testPDFBoxSaveAsImage() throws Exception {
PDDocument document = PDDocument.load(selectPDF().getBytes())
PDFRenderer pdfRenderer = new PDFRenderer(document)
for (int page = 0; page < document.getNumberOfPages(); ++page) {
BufferedImage bim = pdfRenderer.renderImageWithDPI(page,300, ImageType.BINARY)
// suffix in filename will be used as the file format
OutputStream fileOutputStream = new FileOutputStream(+ System.nanoTime() + ".png")
boolean b = ImageIOUtil.writeImage(bim, "png",fileOutputStream,300)
}
document.close()
println "Extraction complete"
}
}

Grails Generating a zip file for the user to download

I am a newbie to grails currently working on a web-app project that works with users uploading pictures. Users can create a "hunt" with a list of prompts. Each "prompt" is the objective for participants (eg: upload pictures of your favorite candy.) Basically the web-app is a "scavenger hunt" tool for Photographers to socially share their work.
Right now, I am having trouble trying write a function in my user controller to generate a zip file with all of the pictures that the user has uploaded. This is what my controller function looks like at the moment.
I used this example I found to start.
Generating a zip file.
def downloadAlbum(){
ByteArrayOutputStream baos = new ByteArrayOutputStream()
ZipOutputStream zipFile = new ZipOutputStream(baos)
//Instance of a user domain class
def userInstance = User.findByLogin(auth.user())
//pictures are uploaded to a prompt and stored as a photoInstance
//this line of code gets the actual file stored as byte[]
photoInstance.myFile = image.getBytes()
//select all photos that belong to the user and store them into a list
def photoInstanceList = userInstance ? Photo.findAllByMyUser(userInstance) : []
//Mapping
[userInstance: userInstance, photoInstanceList: photoInstanceList]
photoInstanceList.each {photo ->
if (photoInstance.myFile != "") {
File file = new File(photoInstance.myFile)
zipFile.putNextEntry(new ZipEntry(Photo.title+".jpeg"))
file.withInputStream { i ->
zipFile << i
}
zipFile.closeEntry()
}
}
zipFile.finish()
response.setHeader("Content-disposition", "filename=\"${login}.zip\"")
response.contentType = "application/zip"
response.outputStream << baos.toByteArray()
response.outputStream.flush()
}
I then use this code in the User view to generate a link that calls the function in the user controller. Am I close? Is there some missing piece in my code?
By the way, This is the first question I have ever written on Stack Overflow. I appreciate the time that you have taken to read this entry. If anything is not clear enough, please where I can improve this question. I am using grails 2.1.1
Thank you for your time!!
If the above code has been copied as is here, shouldn't we be using photo.title instead of Photo.title in the below line
zipFile.putNextEntry(new ZipEntry(Photo.title+".jpeg"))

Resources