user771912
user771912

Reputation: 411

can a jpeg image be generated programatically?

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

Answers (2)

bartoleo
bartoleo

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

Mac O&#39;Brien
Mac O&#39;Brien

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

Related Questions