Reputation: 411
I'm unit testing a block of code that has this line
ExifSubIFDDirectory directory = ImageMetadataReader
.readMetadata(new File(uploadedFile.currentPath))
.getDirectory(ExifSubIFDDirectory.class)
ImageMetadataReader expects a jpeg file, otherwise the code fails. I tried creating a jpeg file with this
LocalDate localDate = LocalDate.now()
def filePath = localDate.toString() + ".jpeg"
def fileStore = new File(filePath);
fileStore.createNewFile(); // creates file with .jpeg extension
Despite a file being made with a jpeg extension, it knows it's not an image and I get this
not a jpeg file
com.drew.imaging.jpeg.JpegProcessingException: not a jpeg file
at com.drew.imaging.jpeg.JpegSegmentReader.readSegments(JpegSegmentReader.java:212)
at com.drew.imaging.jpeg.JpegSegmentReader.<init>(JpegSegmentReader.java:107)
at com.drew.imaging.jpeg.JpegMetadataReader.readMetadata(JpegMetadataReader.java:70)
at com.drew.imaging.ImageMetadataReader.readMetadata(ImageMetadataReader.java:108)
at com.drew.imaging.ImageMetadataReader.readMetadata(ImageMetadataReader.java:95)
at com.witsmd.pronghorn.ConvertToDicomService.$tt__getExifTimestamp(ConvertToDicomService.groovy:164)
at com.witsmd.pronghorn.ConvertToDicomServiceSpec.(ConvertToDicomServiceSpec.groovy:156)
I could just place an actual jpeg file in my project and just use that as an example but I rather be able to create an image, save it, test the method, then delete the jpeg file. Is that possible?
Upvotes: 0
Views: 943
Reputation: 299
you can use this java class to generate a random jpeg image file
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class JpegGenerator {
public static void generate(String fileName, int width, int height, int pixSize) throws Exception {
int x, y = 0;
BufferedImage bi = new BufferedImage(pixSize * width, pixSize * height, BufferedImage.TYPE_3BYTE_BGR);
Graphics2D g = (Graphics2D) bi.getGraphics();
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
x = i * pixSize;
y = j * pixSize;
if ((i * j) % 6 == 0) {
g.setColor(Color.GRAY);
} else if ((i + j) % 5 == 0) {
g.setColor(Color.BLUE);
} else {
g.setColor(Color.WHITE);
}
g.fillRect(y, x, pixSize, pixSize);
}
}
g.dispose();
saveToFile(bi, new File(fileName));
}
/**
* Saves jpeg to file
*/
public static void saveToFile(BufferedImage img, File file) throws IOException {
ImageWriter writer = null;
java.util.Iterator iter = ImageIO.getImageWritersByFormatName("jpg");
if (iter.hasNext()) {
writer = (ImageWriter) iter.next();
}
ImageOutputStream ios = ImageIO.createImageOutputStream(file);
writer.setOutput(ios);
ImageWriteParam param = new JPEGImageWriteParam(java.util.Locale.getDefault());
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(0.98f);
writer.write(null, new IIOImage(img, null, null), param);
}
}
example call:
JpegGenerator.generate("/tmp/myfile.jpg",100,100,5
Upvotes: 0
Reputation: 2907
The program couldn't care less about the file extension. This misconception is sort of the fault of Windows -- file extensions were originally only intended for humans to figure out what a file did. Most file formats have what's called a header section that defines how the document should be read; HTML and XML are both good examples of this. As such, you can't pass just any file with a *.jpg extension and expect it to work.
If you want to manually create a JPEG file, you'll have to read up on the specification and find a library for grails that can write them from raw data. I doubt that this knowledge is critical to your testing, however, and would recommend keeping it simple.
Upvotes: 3