Тест javax.imageIo при весенней загрузке не находит читателя - PullRequest
0 голосов
/ 30 мая 2020

в настоящее время я бы хотел, чтобы этот тест работал в моей весенней загрузке. Это простой модульный тест функции изменения размера изображения с использованием imageIo, он проверяет, что изменение размера не затрагивает какие-либо данные exif и делает изображение меньшего размера по запросу.
Эта функция работает при запуске сервера, но не работает в модуле тест на том же изображении.

говоря следующее:

No reader found
java.lang.IllegalArgumentException: No reader found
    at com.apparence.enlaps.services.pictures.editor.BasicThumbPictureAdapter.resize(BasicThumbPictureAdapter.java:39)
    at com.apparence.enlaps.services.pictures.PictureEditorTest.resizeJpgTest(PictureEditorTest.java:70)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)

Вот код модульного теста. Как я могу сделать это, я считаю, что отсутствие правильной загрузки всех методов чтения в контексте модульного теста - это вопрос контекста. Но моя попытка принудительно загрузить их, похоже, тоже не работает. У меня нет решений.

package com.apparence.enlaps.services.pictures;

import com.apparence.enlaps.services.pictures.editor.BasicThumbPictureAdapter;
import com.apparence.enlaps.services.pictures.editor.exceptions.ResizeException;
import com.twelvemonkeys.image.ImageUtil;
import com.twelvemonkeys.imageio.metadata.CompoundDirectory;
import com.twelvemonkeys.imageio.metadata.exif.EXIFReader;
import com.twelvemonkeys.imageio.metadata.jpeg.JPEG;
import com.twelvemonkeys.imageio.metadata.jpeg.JPEGSegment;
import com.twelvemonkeys.imageio.metadata.jpeg.JPEGSegmentUtil;
import com.twelvemonkeys.imageio.metadata.tiff.TIFF;
import com.twelvemonkeys.imageio.metadata.tiff.TIFFReader;
import com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReaderSpi;
import com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageWriterSpi;
import com.twelvemonkeys.imageio.plugins.tiff.TIFFImageReaderSpi;
import com.twelvemonkeys.imageio.plugins.tiff.TIFFImageWriterSpi;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.test.context.SpringBootContextLoader;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import org.junit.Assert;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.spi.IIORegistry;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.MemoryCacheImageInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;


@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@ActiveProfiles("test")
@DirtiesContext
public class PictureEditorTest {

    BasicThumbPictureAdapter adapter = new BasicThumbPictureAdapter();

    @Before
    public void init() {
        ImageIO.scanForPlugins();
        IIORegistry registry = IIORegistry.getDefaultInstance();
        registry.registerApplicationClasspathSpis();
    }

    // BROKEN test cauz of https://stackoverflow.com/questions/49270343/imageio-unsupported-image-type-twelvemonkeys-plugin-with-fix-not-working
    // IMAGEIO drivers not loaded in test context
    @Test
    public void resizeJpgTest() throws IOException, ResizeException {
        Resource resource = new ClassPathResource("img/test2.jpg");
        Assert.assertNotNull("image to check resize exists", resource);
        Assert.assertTrue("image to check resize exists", resource.exists());
        Assert.assertTrue("image to check resize exists", resource.getFile().exists());
        var is = resource.getInputStream();
        Assert.assertTrue("image to check resize exists", is.available() > 0);
        CompoundDirectory sourceExif = getExifData(is);
        Assert.assertNotNull("Source exif have been read", sourceExif);
        // call resize
        var result = adapter.resize(is, 800);
        // check results
        try (var resultIs = new ByteArrayInputStream(result)) {
            ImageInputStream imageIs = ImageIO.createImageInputStream(resultIs);
            Iterator<ImageReader> readers = ImageIO.getImageReaders(imageIs);
            if (!readers.hasNext()) {
                throw new IllegalArgumentException("No reader found");
            }
            ImageReader reader = readers.next();
            reader.setInput(imageIs);
            Assert.assertEquals("JPEG", reader.getFormatName());
            CompoundDirectory exif = getExifData(resultIs);
            Assert.assertNotNull(exif);
            Assert.assertTrue("width should be <= 800 now", reader.getWidth(0) <= 800);
            Assert.assertTrue("height should be <= 800 now", reader.getHeight(0) <= 800);
            Assert.assertEquals("Orientation has not changed", 5, exif.getEntryByFieldName("orientation").getValue());
        } catch (Exception e) {
            throw new RuntimeException("error while reading result", e);
        }
    }

    private CompoundDirectory getExifData(InputStream resultIs) throws IOException {
        List<JPEGSegment> exifSegment = JPEGSegmentUtil.readSegments(ImageIO.createImageInputStream(resultIs), JPEG.APP1, "Exif");
        if (!exifSegment.isEmpty()) {
            InputStream exifData = exifSegment.get(0).data();
            exifData.read(); // Skip 0-pad for Exif in JFIF
            try (ImageInputStream exifStream = ImageIO.createImageInputStream(exifData)) {
                return (CompoundDirectory) new TIFFReader().read(exifStream);
            }
        }
        return null;
    }
}
...