Project

General

Profile

« Previous | Next » 

Revision 9d43097c

Added by Andreas Müller almost 4 years ago

ref #9148 change the name of CDM class ImageInfo to CdmImageInfo to avoid name calsh with commons-imaging/ImageInfo

View differences:

cdmlib-commons/src/main/java/eu/etaxonomy/cdm/common/media/CdmImageInfo.java
1
/**
2
* Copyright (C) 2009 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.common.media;
10

  
11
import java.io.IOException;
12
import java.io.InputStream;
13
import java.net.URI;
14
import java.util.HashMap;
15
import java.util.Map;
16

  
17
import org.apache.commons.imaging.ImageInfo;
18
import org.apache.commons.imaging.ImageReadException;
19
import org.apache.commons.imaging.Imaging;
20
import org.apache.commons.imaging.common.GenericImageMetadata.GenericImageMetadataItem;
21
import org.apache.commons.imaging.common.ImageMetadata;
22
import org.apache.commons.imaging.common.ImageMetadata.ImageMetadataItem;
23
import org.apache.commons.lang.StringUtils;
24
import org.apache.http.HttpException;
25
import org.apache.http.client.ClientProtocolException;
26
import org.apache.log4j.Logger;
27

  
28
import eu.etaxonomy.cdm.common.UriUtils;
29

  
30
/**
31
 * @author k.luther
32
 * @author a.mueller
33
 * @since 27.11.2009
34
 */
35
public  class CdmImageInfo extends MediaInfo {
36
	private static Logger logger = Logger.getLogger(CdmImageInfo.class);
37

  
38
	private int width;
39
	private int height;
40
	private int bitPerPixel;
41
	private final URI imageUri;
42

  
43
	private Map<String, String> metaData;
44

  
45
//********************** Factory Methods ******************************/
46

  
47
	public static CdmImageInfo NewInstance(URI imageUri, Integer timeOut) throws IOException, HttpException {
48
		CdmImageInfo instance = new CdmImageInfo(imageUri);
49
		instance.readSuffix();
50
		instance.readImageLength();
51
		instance.readImageInfo(timeOut);
52
		return instance;
53
	}
54

  
55
	public static CdmImageInfo NewInstanceWithMetaData(URI imageUri, Integer timeOut) throws IOException, HttpException {
56
		CdmImageInfo instance = NewInstance(imageUri, timeOut);
57

  
58
		instance.readMetaData(timeOut);
59

  
60
		return instance;
61
	}
62

  
63
//*********************** CONSTRUCTOR **************************************/
64

  
65
	private CdmImageInfo(URI imageUri){
66
		this.imageUri = imageUri;
67
	}
68

  
69
//*************************** GETTER /SETTER *******************************/
70

  
71
	public URI getUri() {
72
		return imageUri;
73
	}
74

  
75
	public int getWidth() {
76
		return width;
77
	}
78

  
79
	public int getHeight() {
80
		return height;
81
	}
82

  
83
	public int getBitPerPixel() {
84
		return bitPerPixel;
85
	}
86

  
87
	public Map<String, String> getMetaData(){
88
		return metaData;
89
	}
90

  
91
//**************************** METHODS *****************************/
92

  
93
	private void readSuffix(){
94
		String path = imageUri.getPath();
95

  
96
		String suffix = path.substring(StringUtils.lastIndexOf(path, '.') + 1);
97
		setSuffix(suffix);
98
	}
99

  
100
	private void readImageLength() throws ClientProtocolException, IOException, HttpException{
101
		try {
102
            long length = UriUtils.getResourceLength(imageUri, null);
103
            setLength(length);
104
        } catch (HttpException e) {
105
            if (e.getMessage().equals("Could not retrieve Content-Length")){
106
                InputStream inputStream = UriUtils.getInputStream(imageUri);
107
                int n = 0;
108
                while(inputStream.read() != -1){
109
                    n++;
110
                }
111
                inputStream.close();
112
                logger.info("Content-Length not available in http header. Image size computed via input stream size: " + imageUri);
113
                setLength(n);
114
            }else{
115
                throw e;
116
            }
117
        }
118
	}
119

  
120
	/**
121
	 * Reads the image infos (width, height, bitPerPixel, metadata, format, mime type)
122
	 * @param timeOut
123
	 * @throws IOException
124
	 * @throws HttpException
125
	 */
126
	private void readImageInfo(Integer timeOut) throws IOException, HttpException{
127

  
128
		InputStream inputStream;
129
		try {
130
			inputStream = UriUtils.getInputStream(imageUri);
131
			ImageInfo imageInfo = Imaging.getImageInfo(inputStream, null);
132

  
133
			setFormatName(imageInfo.getFormatName());
134
			setMimeType(imageInfo.getMimeType());
135
			width = imageInfo.getWidth();
136
			height = imageInfo.getHeight();
137
			bitPerPixel = imageInfo.getBitsPerPixel();
138
			inputStream.close();
139

  
140
		} catch (ImageReadException e) {
141
			logger.error("Could not read: " + imageUri + ". " + e.getMessage());
142
			throw new IOException(e);
143
		}
144
	}
145

  
146

  
147
	/**
148
	 * @param timeOut TODO is not yet used
149
	 * @return
150
	 * @throws IOException
151
	 * @throws HttpException
152
	 */
153
	public Map<String, String> readMetaData(Integer timeOut) throws IOException, HttpException {
154

  
155
		try {
156
			InputStream inputStream = UriUtils.getInputStream(imageUri);
157

  
158
			ImageMetadata mediaData = Imaging.getMetadata(inputStream, null);
159

  
160
			if (mediaData != null){
161
				metaData = new HashMap<>();
162
				for (ImageMetadataItem item2 : mediaData.getItems()){
163
					if (item2 instanceof GenericImageMetadataItem){
164
					    GenericImageMetadataItem item = (GenericImageMetadataItem)item2;
165
					    if (item.getKeyword().contains("/")){
166
					        String key = item.getKeyword();
167
					        //key.replace("/", "");
168
					        int index = key.indexOf("/");
169
					        key = key.substring(0, index);
170
					        metaData.put(key, text(item));
171
					    }else{
172
					        metaData.put(item.getKeyword(), text(item));
173
					    }
174
					}
175
				}
176
			}
177
		}
178
		catch (ImageReadException e) {
179
			logger.error("Could not read: " + imageUri + ". " + e.getMessage());
180
			//throw new IOException(e);
181
		}
182
		return metaData;
183
	}
184

  
185
    /**
186
     * Wrapper for the Item.getText() method which applies cleaning of the text representation.
187
     *
188
     * <ol>
189
     * <li>Strings are surrounded by single quotes, these must be removed</li>
190
     * </ol>
191
     * @param item
192
     */
193
    private String text(GenericImageMetadataItem item) {
194
        String  text = item.getText();
195
        if(text.startsWith("'") && text.endsWith("'")) {
196
            text = text.substring(1 , text.length() - 1);
197
        }
198
        return text;
199
    }
200

  
201
// ******************* TO STRING **********************************/
202

  
203
	@Override
204
	public String toString(){
205
        return getFormatName() + " [" + getMimeType()+ "] w:" + width + " h:" + height + " depth:" + bitPerPixel;
206
	}
207
}
cdmlib-commons/src/main/java/eu/etaxonomy/cdm/common/media/ImageInfo.java
1
/**
2
* Copyright (C) 2009 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.common.media;
10

  
11
import java.io.IOException;
12
import java.io.InputStream;
13
import java.net.URI;
14
import java.util.HashMap;
15
import java.util.Map;
16

  
17
import org.apache.commons.imaging.ImageReadException;
18
import org.apache.commons.imaging.Imaging;
19
import org.apache.commons.imaging.common.GenericImageMetadata.GenericImageMetadataItem;
20
import org.apache.commons.imaging.common.ImageMetadata;
21
import org.apache.commons.imaging.common.ImageMetadata.ImageMetadataItem;
22
import org.apache.commons.lang.StringUtils;
23
import org.apache.http.HttpException;
24
import org.apache.http.client.ClientProtocolException;
25
import org.apache.log4j.Logger;
26

  
27
import eu.etaxonomy.cdm.common.UriUtils;
28

  
29
/**
30
 * @author k.luther
31
 * @author a.mueller
32
 * @since 27.11.2009
33
 */
34
public  class ImageInfo extends MediaInfo {
35
	private static Logger logger = Logger.getLogger(ImageInfo.class);
36

  
37
	private int width;
38
	private int height;
39
	private int bitPerPixel;
40
	private final URI imageUri;
41

  
42
	private Map<String, String> metaData;
43

  
44
//********************** Factory Methods ******************************/
45

  
46
	public static ImageInfo NewInstance(URI imageUri, Integer timeOut) throws IOException, HttpException {
47
		ImageInfo instance = new ImageInfo(imageUri);
48
		instance.readSuffix();
49
		instance.readImageLength();
50
		instance.readImageInfo(timeOut);
51
		return instance;
52
	}
53

  
54
	public static ImageInfo NewInstanceWithMetaData(URI imageUri, Integer timeOut) throws IOException, HttpException {
55
		ImageInfo instance = NewInstance(imageUri, timeOut);
56

  
57
		instance.readMetaData(timeOut);
58

  
59
		return instance;
60
	}
61

  
62
//*********************** CONSTRUCTOR **************************************/
63

  
64
	private ImageInfo(URI imageUri){
65
		this.imageUri = imageUri;
66
	}
67

  
68
//*************************** GETTER /SETTER *******************************/
69

  
70
	public URI getUri() {
71
		return imageUri;
72
	}
73

  
74
	public int getWidth() {
75
		return width;
76
	}
77

  
78
	public int getHeight() {
79
		return height;
80
	}
81

  
82
	public int getBitPerPixel() {
83
		return bitPerPixel;
84
	}
85

  
86
	public Map<String, String> getMetaData(){
87
		return metaData;
88
	}
89

  
90
//**************************** METHODS *****************************/
91

  
92
	private void readSuffix(){
93
		String path = imageUri.getPath();
94

  
95
		String suffix = path.substring(StringUtils.lastIndexOf(path, '.') + 1);
96
		setSuffix(suffix);
97
	}
98

  
99
	private void readImageLength() throws ClientProtocolException, IOException, HttpException{
100
		try {
101
            long length = UriUtils.getResourceLength(imageUri, null);
102
            setLength(length);
103
        } catch (HttpException e) {
104
            if (e.getMessage().equals("Could not retrieve Content-Length")){
105
                InputStream inputStream = UriUtils.getInputStream(imageUri);
106
                int n = 0;
107
                while(inputStream.read() != -1){
108
                    n++;
109
                }
110
                inputStream.close();
111
                logger.info("Content-Length not available in http header. Image size computed via input stream size: " + imageUri);
112
                setLength(n);
113
            }else{
114
                throw e;
115
            }
116
        }
117
	}
118

  
119
	/**
120
	 * Reads the image infos (width, height, bitPerPixel, metadata, format, mime type)
121
	 * @param timeOut
122
	 * @throws IOException
123
	 * @throws HttpException
124
	 */
125
	private void readImageInfo(Integer timeOut) throws IOException, HttpException{
126

  
127
		InputStream inputStream;
128
		try {
129
			inputStream = UriUtils.getInputStream(imageUri);
130
			ImageInfo imageInfo = Imaging.getImageInfo(inputStream, null);
131

  
132
			setFormatName(imageInfo.getFormatName());
133
			setMimeType(imageInfo.getMimeType());
134
			width = imageInfo.getWidth();
135
			height = imageInfo.getHeight();
136
			bitPerPixel = imageInfo.getBitsPerPixel();
137
			inputStream.close();
138

  
139
		} catch (ImageReadException e) {
140
			logger.error("Could not read: " + imageUri + ". " + e.getMessage());
141
			throw new IOException(e);
142
		}
143
	}
144

  
145

  
146
	/**
147
	 * @param timeOut TODO is not yet used
148
	 * @return
149
	 * @throws IOException
150
	 * @throws HttpException
151
	 */
152
	public Map<String, String> readMetaData(Integer timeOut) throws IOException, HttpException {
153

  
154
		try {
155
			InputStream inputStream = UriUtils.getInputStream(imageUri);
156

  
157
			ImageMetadata mediaData = Imaging.getMetadata(inputStream, null);
158

  
159
			if (mediaData != null){
160
				metaData = new HashMap<>();
161
				for (ImageMetadataItem item2 : mediaData.getItems()){
162
					if (item2 instanceof GenericImageMetadataItem){
163
					    GenericImageMetadataItem item = (GenericImageMetadataItem)item2;
164
					    if (item.getKeyword().contains("/")){
165
					        String key = item.getKeyword();
166
					        //key.replace("/", "");
167
					        int index = key.indexOf("/");
168
					        key = key.substring(0, index);
169
					        metaData.put(key, text(item));
170
					    }else{
171
					        metaData.put(item.getKeyword(), text(item));
172
					    }
173
					}
174
				}
175
			}
176
		}
177
		catch (ImageReadException e) {
178
			logger.error("Could not read: " + imageUri + ". " + e.getMessage());
179
			//throw new IOException(e);
180
		}
181
		return metaData;
182
	}
183

  
184
    /**
185
     * Wrapper for the Item.getText() method which applies cleaning of the text representation.
186
     *
187
     * <ol>
188
     * <li>Strings are surrounded by single quotes, these must be removed</li>
189
     * </ol>
190
     * @param item
191
     */
192
    private String text(GenericImageMetadataItem item) {
193
        String  text = item.getText();
194
        if(text.startsWith("'") && text.endsWith("'")) {
195
            text = text.substring(1 , text.length() - 1);
196
        }
197
        return text;
198
    }
199

  
200
// ******************* TO STRING **********************************/
201

  
202
	@Override
203
	public String toString(){
204
        return getFormatName() + " [" + getMimeType()+ "] w:" + width + " h:" + height + " depth:" + bitPerPixel;
205
	}
206
}
cdmlib-commons/src/test/java/eu/etaxonomy/cdm/common/media/CdmImageInfoTest.java
1
/**
2
 *
3
 */
4
package eu.etaxonomy.cdm.common.media;
5

  
6
import static org.junit.Assert.fail;
7

  
8
import java.io.IOException;
9
import java.net.URI;
10
import java.net.URL;
11
import java.util.Map;
12

  
13
import org.apache.http.HttpException;
14
import org.apache.log4j.Logger;
15
import org.junit.Assert;
16
import org.junit.Before;
17
import org.junit.Test;
18

  
19
import eu.etaxonomy.cdm.common.UriUtils;
20

  
21
/**
22
 * @author n.hoffmann
23
 */
24
public class CdmImageInfoTest {
25

  
26
    private static final String OFFLINE = "OFFLINE";
27

  
28
    public static final Logger logger = Logger.getLogger(CdmImageInfoTest.class);
29

  
30
    private URI jpegUri;
31
    private URI tiffUri;
32
    private CdmImageInfo jpegInstance;
33
    private CdmImageInfo tifInstance;
34

  
35
    private URI remotePngUri;
36
    private CdmImageInfo pngInstance;
37

  
38
    /**
39
     * @throws java.lang.Exception
40
     */
41
    @Before
42
    public void setUp() throws Exception {
43
        URL jpegUrl = CdmImageInfoTest.class.getResource("/images/OregonScientificDS6639-DSC_0307-small.jpg");
44
        jpegUri = jpegUrl.toURI();
45

  
46
        URL tiffUrl = CdmImageInfoTest.class.getResource("/images/OregonScientificDS6639-DSC_0307-small.tif");
47
        tiffUri = tiffUrl.toURI();
48

  
49
        remotePngUri = URI.create("https://dev.e-taxonomy.eu/trac_htdocs/logo_edit.png");
50
    }
51

  
52
    @Test
53
    public void testNewInstanceJpeg(){
54
        try {
55
            CdmImageInfo.NewInstance(jpegUri, 0);
56
        } catch (Exception e) {
57
            fail("NewInstance method should not throw exceptions for existing uncorrupted images.");
58
        }
59
    }
60

  
61
    @Test
62
    public void testNewInstanceTiff() {
63
        try {
64
            CdmImageInfo.NewInstance(tiffUri, 0);
65
        } catch (Exception e) {
66
            fail("NewInstance method should not throw exceptions for existing uncorrupted images.");
67
        }
68
    }
69

  
70
    @Test
71
    public void testNewInstanceRemotePng() {
72
        if(UriUtils.isInternetAvailable(remotePngUri)){
73
            try {
74
                CdmImageInfo.NewInstance(remotePngUri, 3000);
75
            } catch (Exception e) {
76
                fail("NewInstance method should not throw exceptions for existing uncorrupted images.");
77
            }
78
        } else {
79
            logger.warn("test testNewInstanceRemotePng() skipped, since server is not available");
80
        }
81
    }
82

  
83
    @Test(expected=IOException.class)
84
    public void testNewInstanceFileDoesNotExist() throws HttpException, IOException {
85
        URI nonExistentUri = URI.create("file:///nonExistentImage.jpg");
86

  
87
        CdmImageInfo.NewInstance(nonExistentUri, 0);
88
    }
89

  
90
    private CdmImageInfo getJpegInstance(){
91
        if(jpegInstance == null){
92
            try {
93
                jpegInstance = CdmImageInfo.NewInstance(jpegUri, 0);
94
            } catch (Exception e) {
95
                fail("This case should have been covered by other tests.");
96
                return null;
97
            }
98
        }
99
        return jpegInstance;
100
    }
101

  
102
    private CdmImageInfo getTifInstance(){
103
        if(tifInstance == null){
104
            try {
105
                tifInstance = CdmImageInfo.NewInstance(tiffUri, 0);
106
            } catch (Exception e) {
107
                fail("This case should have been covered by other tests.");
108
                return null;
109
            }
110
        }
111
        return tifInstance;
112
    }
113

  
114
    private CdmImageInfo getRemotePngInstance() throws IOException{
115
        if (!UriUtils.isInternetAvailable(remotePngUri)){
116
            throw new IOException(OFFLINE);
117
        }
118
        if(pngInstance == null){
119
            try {
120
                pngInstance = CdmImageInfo.NewInstance(remotePngUri, 3000);
121
            } catch (Exception e) {
122
                fail("This case should have been covered by other tests.");
123
                return null;
124
            }
125
        }
126
        return pngInstance;
127
    }
128

  
129
    /**
130
     * Test method for {@link eu.etaxonomy.cdm.common.media.CdmImageInfo#getWidth()}.
131
     */
132
    @Test
133
    public void testGetWidth() {
134
        Assert.assertEquals(300, getJpegInstance().getWidth());
135
        Assert.assertEquals(300, getTifInstance().getWidth());
136

  
137
        try {
138
            Assert.assertEquals(93, getRemotePngInstance().getWidth());
139
        } catch (IOException e){
140
            if(e.getMessage().equals(OFFLINE)){
141
                logger.warn("test part skipped, since server is not available.");
142
            }
143
        }
144
    }
145

  
146
    /**
147
     * Test method for {@link eu.etaxonomy.cdm.common.media.CdmImageInfo#getHeight()}.
148
     */
149
    @Test
150
    public void testGetHeight() {
151
        Assert.assertEquals(225, getJpegInstance().getHeight());
152
        Assert.assertEquals(225, getTifInstance().getHeight());
153

  
154
        try {
155
            Assert.assertEquals(93, getRemotePngInstance().getHeight());
156
        } catch (IOException e){
157
            if(e.getMessage().equals(OFFLINE)){
158
                logger.warn("test part skipped, since server is not available.");
159
            }
160
        }
161
    }
162

  
163
    /**
164
     * Test method for {@link eu.etaxonomy.cdm.common.media.CdmImageInfo#getBitPerPixel()}.
165
     */
166
    @Test
167
    public void testGetBitPerPixel() {
168
        Assert.assertEquals(24, getJpegInstance().getBitPerPixel());
169
        Assert.assertEquals(24, getTifInstance().getBitPerPixel());
170

  
171
        try {
172
            Assert.assertEquals(32, getRemotePngInstance().getBitPerPixel());
173
        } catch (IOException e){
174
            if(e.getMessage().equals(OFFLINE)){
175
                logger.warn("test part skipped, since server is not available.");
176
            }
177
        }
178
    }
179

  
180
    /**
181
     * Test method for {@link eu.etaxonomy.cdm.common.media.CdmImageInfo#getFormatName()}.
182
     */
183
    @Test
184
    public void testGetFormatName() {
185
        Assert.assertEquals("JPEG (Joint Photographic Experts Group) Format", getJpegInstance().getFormatName());
186
        Assert.assertEquals("TIFF Tag-based Image File Format", getTifInstance().getFormatName());
187

  
188
        try {
189
            Assert.assertEquals("PNG Portable Network Graphics", getRemotePngInstance().getFormatName());
190
        } catch (IOException e){
191
            if(e.getMessage().equals(OFFLINE)){
192
                logger.warn("test part skipped, since server is not available.");
193
            }
194
        }
195
    }
196

  
197
    /**
198
     * Test method for {@link eu.etaxonomy.cdm.common.media.CdmImageInfo#getMimeType()}.
199
     */
200
    @Test
201
    public void testGetMimeType() {
202
        Assert.assertEquals(MimeType.JPEG.getMimeType(), getJpegInstance().getMimeType());
203
        Assert.assertEquals(MimeType.TIFF.getMimeType(), getTifInstance().getMimeType());
204

  
205
        try {
206
            Assert.assertEquals(MimeType.PNG.getMimeType(), getRemotePngInstance().getMimeType());
207
        } catch (IOException e){
208
            if(e.getMessage().equals(OFFLINE)){
209
                logger.warn("test part skipped, since server is not available.");
210
            }
211
        }
212
    }
213

  
214
    @Test
215
    public void testGetLength(){
216
        Assert.assertEquals(63500, getJpegInstance().getLength());
217
        Assert.assertEquals(202926, getTifInstance().getLength());
218

  
219
        try {
220
            Assert.assertEquals(9143, getRemotePngInstance().getLength());
221
        } catch (IOException e){
222
            if(e.getMessage().equals(OFFLINE)){
223
                logger.warn("test part skipped, since server is not available.");
224
            }
225
        }
226
    }
227

  
228
    @Test
229
    public void testGetSuffix(){
230
        Assert.assertEquals("jpg", getJpegInstance().getSuffix());
231
        Assert.assertEquals("tif", getTifInstance().getSuffix());
232

  
233
        try {
234
            Assert.assertEquals("png", getRemotePngInstance().getSuffix());
235
        } catch (IOException e){
236
            if(e.getMessage().equals(OFFLINE)){
237
                logger.warn("test part skipped, since server is not available.");
238
            }
239
        }
240
    }
241

  
242

  
243

  
244
    @Test
245
    public void testReadMetaDataJpeg() throws IOException, HttpException{
246
        CdmImageInfo instance = getJpegInstance();
247

  
248
        instance.readMetaData(0);
249

  
250
        Map<String, String> metaData = instance.getMetaData();
251

  
252
        Assert.assertEquals(48, metaData.size());
253
    }
254

  
255

  
256
    @Test
257
    public void testReadMetaDataTif() throws IOException, HttpException{
258
        CdmImageInfo instance = getTifInstance();
259

  
260
        instance.readMetaData(0);
261

  
262
        Map<String, String> metaData = instance.getMetaData();
263

  
264
        Assert.assertEquals(15, metaData.size());
265
    }
266

  
267
    @Test
268
    public void testReadMetaDataRemotePng() throws HttpException{
269

  
270
        try {
271
            CdmImageInfo instance = getRemotePngInstance();
272

  
273
            instance.readMetaData(3000);
274

  
275
            Map<String, String> metaData = instance.getMetaData();
276

  
277
            Assert.assertEquals(1, metaData.size());
278

  
279
        } catch (IOException e){
280
            if(e.getMessage().equals(OFFLINE)){
281
                logger.warn("test testReadMetaDataRemotePng() skipped, since server is not available.");
282
            }
283
        }
284

  
285

  
286
    }
287
}
cdmlib-commons/src/test/java/eu/etaxonomy/cdm/common/media/ImageInfoTest.java
1
/**
2
 *
3
 */
4
package eu.etaxonomy.cdm.common.media;
5

  
6
import static org.junit.Assert.fail;
7

  
8
import java.io.IOException;
9
import java.net.URI;
10
import java.net.URL;
11
import java.util.Map;
12

  
13
import org.apache.http.HttpException;
14
import org.apache.log4j.Logger;
15
import org.junit.Assert;
16
import org.junit.Before;
17
import org.junit.Test;
18

  
19
import eu.etaxonomy.cdm.common.UriUtils;
20

  
21
/**
22
 * @author n.hoffmann
23
 */
24
public class ImageInfoTest {
25

  
26
    private static final String OFFLINE = "OFFLINE";
27

  
28
    public static final Logger logger = Logger.getLogger(ImageInfoTest.class);
29

  
30
    private URI jpegUri;
31
    private URI tiffUri;
32
    private ImageInfo jpegInstance;
33
    private ImageInfo tifInstance;
34

  
35
    private URI remotePngUri;
36
    private ImageInfo pngInstance;
37

  
38
    /**
39
     * @throws java.lang.Exception
40
     */
41
    @Before
42
    public void setUp() throws Exception {
43
        URL jpegUrl = ImageInfoTest.class.getResource("/images/OregonScientificDS6639-DSC_0307-small.jpg");
44
        jpegUri = jpegUrl.toURI();
45

  
46
        URL tiffUrl = ImageInfoTest.class.getResource("/images/OregonScientificDS6639-DSC_0307-small.tif");
47
        tiffUri = tiffUrl.toURI();
48

  
49
        remotePngUri = URI.create("https://dev.e-taxonomy.eu/trac_htdocs/logo_edit.png");
50
    }
51

  
52
    @Test
53
    public void testNewInstanceJpeg(){
54
        try {
55
            ImageInfo.NewInstance(jpegUri, 0);
56
        } catch (Exception e) {
57
            fail("NewInstance method should not throw exceptions for existing uncorrupted images.");
58
        }
59
    }
60

  
61
    @Test
62
    public void testNewInstanceTiff() {
63
        try {
64
            ImageInfo.NewInstance(tiffUri, 0);
65
        } catch (Exception e) {
66
            fail("NewInstance method should not throw exceptions for existing uncorrupted images.");
67
        }
68
    }
69

  
70
    @Test
71
    public void testNewInstanceRemotePng() {
72
        if(UriUtils.isInternetAvailable(remotePngUri)){
73
            try {
74
                ImageInfo.NewInstance(remotePngUri, 3000);
75
            } catch (Exception e) {
76
                fail("NewInstance method should not throw exceptions for existing uncorrupted images.");
77
            }
78
        } else {
79
            logger.warn("test testNewInstanceRemotePng() skipped, since server is not available");
80
        }
81
    }
82

  
83
    @Test(expected=IOException.class)
84
    public void testNewInstanceFileDoesNotExist() throws HttpException, IOException {
85
        URI nonExistentUri = URI.create("file:///nonExistentImage.jpg");
86

  
87
        ImageInfo.NewInstance(nonExistentUri, 0);
88
    }
89

  
90
    private ImageInfo getJpegInstance(){
91
        if(jpegInstance == null){
92
            try {
93
                jpegInstance = ImageInfo.NewInstance(jpegUri, 0);
94
            } catch (Exception e) {
95
                fail("This case should have been covered by other tests.");
96
                return null;
97
            }
98
        }
99
        return jpegInstance;
100
    }
101

  
102
    private ImageInfo getTifInstance(){
103
        if(tifInstance == null){
104
            try {
105
                tifInstance = ImageInfo.NewInstance(tiffUri, 0);
106
            } catch (Exception e) {
107
                fail("This case should have been covered by other tests.");
108
                return null;
109
            }
110
        }
111
        return tifInstance;
112
    }
113

  
114
    private ImageInfo getRemotePngInstance() throws IOException{
115
        if (!UriUtils.isInternetAvailable(remotePngUri)){
116
            throw new IOException(OFFLINE);
117
        }
118
        if(pngInstance == null){
119
            try {
120
                pngInstance = ImageInfo.NewInstance(remotePngUri, 3000);
121
            } catch (Exception e) {
122
                fail("This case should have been covered by other tests.");
123
                return null;
124
            }
125
        }
126
        return pngInstance;
127
    }
128

  
129
    /**
130
     * Test method for {@link eu.etaxonomy.cdm.common.media.ImageInfo#getWidth()}.
131
     */
132
    @Test
133
    public void testGetWidth() {
134
        Assert.assertEquals(300, getJpegInstance().getWidth());
135
        Assert.assertEquals(300, getTifInstance().getWidth());
136

  
137
        try {
138
            Assert.assertEquals(93, getRemotePngInstance().getWidth());
139
        } catch (IOException e){
140
            if(e.getMessage().equals(OFFLINE)){
141
                logger.warn("test part skipped, since server is not available.");
142
            }
143
        }
144
    }
145

  
146
    /**
147
     * Test method for {@link eu.etaxonomy.cdm.common.media.ImageInfo#getHeight()}.
148
     */
149
    @Test
150
    public void testGetHeight() {
151
        Assert.assertEquals(225, getJpegInstance().getHeight());
152
        Assert.assertEquals(225, getTifInstance().getHeight());
153

  
154
        try {
155
            Assert.assertEquals(93, getRemotePngInstance().getHeight());
156
        } catch (IOException e){
157
            if(e.getMessage().equals(OFFLINE)){
158
                logger.warn("test part skipped, since server is not available.");
159
            }
160
        }
161
    }
162

  
163
    /**
164
     * Test method for {@link eu.etaxonomy.cdm.common.media.ImageInfo#getBitPerPixel()}.
165
     */
166
    @Test
167
    public void testGetBitPerPixel() {
168
        Assert.assertEquals(24, getJpegInstance().getBitPerPixel());
169
        Assert.assertEquals(24, getTifInstance().getBitPerPixel());
170

  
171
        try {
172
            Assert.assertEquals(32, getRemotePngInstance().getBitPerPixel());
173
        } catch (IOException e){
174
            if(e.getMessage().equals(OFFLINE)){
175
                logger.warn("test part skipped, since server is not available.");
176
            }
177
        }
178
    }
179

  
180
    /**
181
     * Test method for {@link eu.etaxonomy.cdm.common.media.ImageInfo#getFormatName()}.
182
     */
183
    @Test
184
    public void testGetFormatName() {
185
        Assert.assertEquals("JPEG (Joint Photographic Experts Group) Format", getJpegInstance().getFormatName());
186
        Assert.assertEquals("TIFF Tag-based Image File Format", getTifInstance().getFormatName());
187

  
188
        try {
189
            Assert.assertEquals("PNG Portable Network Graphics", getRemotePngInstance().getFormatName());
190
        } catch (IOException e){
191
            if(e.getMessage().equals(OFFLINE)){
192
                logger.warn("test part skipped, since server is not available.");
193
            }
194
        }
195
    }
196

  
197
    /**
198
     * Test method for {@link eu.etaxonomy.cdm.common.media.ImageInfo#getMimeType()}.
199
     */
200
    @Test
201
    public void testGetMimeType() {
202
        Assert.assertEquals(MimeType.JPEG.getMimeType(), getJpegInstance().getMimeType());
203
        Assert.assertEquals(MimeType.TIFF.getMimeType(), getTifInstance().getMimeType());
204

  
205
        try {
206
            Assert.assertEquals(MimeType.PNG.getMimeType(), getRemotePngInstance().getMimeType());
207
        } catch (IOException e){
208
            if(e.getMessage().equals(OFFLINE)){
209
                logger.warn("test part skipped, since server is not available.");
210
            }
211
        }
212
    }
213

  
214
    @Test
215
    public void testGetLength(){
216
        Assert.assertEquals(63500, getJpegInstance().getLength());
217
        Assert.assertEquals(202926, getTifInstance().getLength());
218

  
219
        try {
220
            Assert.assertEquals(9143, getRemotePngInstance().getLength());
221
        } catch (IOException e){
222
            if(e.getMessage().equals(OFFLINE)){
223
                logger.warn("test part skipped, since server is not available.");
224
            }
225
        }
226
    }
227

  
228
    @Test
229
    public void testGetSuffix(){
230
        Assert.assertEquals("jpg", getJpegInstance().getSuffix());
231
        Assert.assertEquals("tif", getTifInstance().getSuffix());
232

  
233
        try {
234
            Assert.assertEquals("png", getRemotePngInstance().getSuffix());
235
        } catch (IOException e){
236
            if(e.getMessage().equals(OFFLINE)){
237
                logger.warn("test part skipped, since server is not available.");
238
            }
239
        }
240
    }
241

  
242

  
243

  
244
    @Test
245
    public void testReadMetaDataJpeg() throws IOException, HttpException{
246
        ImageInfo instance = getJpegInstance();
247

  
248
        instance.readMetaData(0);
249

  
250
        Map<String, String> metaData = instance.getMetaData();
251

  
252
        Assert.assertEquals(48, metaData.size());
253
    }
254

  
255

  
256
    @Test
257
    public void testReadMetaDataTif() throws IOException, HttpException{
258
        ImageInfo instance = getTifInstance();
259

  
260
        instance.readMetaData(0);
261

  
262
        Map<String, String> metaData = instance.getMetaData();
263

  
264
        Assert.assertEquals(15, metaData.size());
265
    }
266

  
267
    @Test
268
    public void testReadMetaDataRemotePng() throws HttpException{
269

  
270
        try {
271
            ImageInfo instance = getRemotePngInstance();
272

  
273
            instance.readMetaData(3000);
274

  
275
            Map<String, String> metaData = instance.getMetaData();
276

  
277
            Assert.assertEquals(1, metaData.size());
278

  
279
        } catch (IOException e){
280
            if(e.getMessage().equals(OFFLINE)){
281
                logger.warn("test testReadMetaDataRemotePng() skipped, since server is not available.");
282
            }
283
        }
284

  
285

  
286
    }
287
}
cdmlib-ext/src/main/java/eu/etaxonomy/cdm/ext/occurrence/gbif/GbifJsonOccurrenceParser.java
25 25

  
26 26
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;
27 27
import eu.etaxonomy.cdm.common.UriUtils;
28
import eu.etaxonomy.cdm.common.media.ImageInfo;
28
import eu.etaxonomy.cdm.common.media.CdmImageInfo;
29 29
import eu.etaxonomy.cdm.model.agent.Institution;
30 30
import eu.etaxonomy.cdm.model.agent.Person;
31 31
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
......
429 429
                    JSONObject mediaRecord;
430 430
                    Media media;
431 431
                    URI uri = null;
432
                    ImageInfo imageInf = null;
432
                    CdmImageInfo imageInf = null;
433 433
                    MediaRepresentation representation = null;
434 434
                    SpecimenOrObservationType type = null;
435 435
                    for(Object object:multimediaArray){
......
444 444
                            if (mediaRecord.has("identifier")){
445 445
                                try {
446 446
                                    uri = new URI(mediaRecord.getString("identifier"));
447
                                    imageInf = ImageInfo.NewInstance(uri, 0);
447
                                    imageInf = CdmImageInfo.NewInstance(uri, 0);
448 448
                                } catch (URISyntaxException |IOException | HttpException e) {
449 449
                                    e.printStackTrace();
450 450
                                }
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/common/CdmImportBase.java
24 24

  
25 25
import eu.etaxonomy.cdm.api.application.ICdmRepository;
26 26
import eu.etaxonomy.cdm.api.service.pager.Pager;
27
import eu.etaxonomy.cdm.common.media.ImageInfo;
27
import eu.etaxonomy.cdm.common.media.CdmImageInfo;
28 28
import eu.etaxonomy.cdm.io.common.mapping.IInputTransformer;
29 29
import eu.etaxonomy.cdm.io.common.mapping.UndefinedTransformerMethodException;
30 30
import eu.etaxonomy.cdm.io.markup.MarkupTransformer;
......
1424 1424
     */
1425 1425
    private MediaRepresentation makeMediaRepresentation(String uriString, boolean readMediaData) throws URISyntaxException {
1426 1426
        uriString = uriString.replace(" ", "%20");  //replace whitespace
1427
        ImageInfo imageInfo = null;
1427
        CdmImageInfo cdmImageInfo = null;
1428 1428
        URI uri = new URI(uriString);
1429 1429

  
1430 1430
        try {
1431 1431
        	if (readMediaData){
1432 1432
        		logger.info("Read media data from: " + uri);
1433
        		imageInfo = ImageInfo.NewInstance(uri, 0);
1433
        		cdmImageInfo = CdmImageInfo.NewInstance(uri, 0);
1434 1434
        	}
1435 1435
        } catch (Exception e) {
1436 1436
        	String message = "An error occurred when trying to read image meta data for " + uri.toString() + ": " +  e.getMessage();
1437 1437
        	logger.warn(message);
1438 1438
        	fireWarningEvent(message, "unknown location", 2, 0);
1439 1439
        }
1440
        ImageFile imageFile = ImageFile.NewInstance(uri, null, imageInfo);
1440
        ImageFile imageFile = ImageFile.NewInstance(uri, null, cdmImageInfo);
1441 1441

  
1442 1442
        MediaRepresentation representation = MediaRepresentation.NewInstance();
1443 1443

  
1444
        if(imageInfo != null){
1445
        	representation.setMimeType(imageInfo.getMimeType());
1446
        	representation.setSuffix(imageInfo.getSuffix());
1444
        if(cdmImageInfo != null){
1445
        	representation.setMimeType(cdmImageInfo.getMimeType());
1446
        	representation.setSuffix(cdmImageInfo.getSuffix());
1447 1447
        }
1448 1448
        representation.addRepresentationPart(imageFile);
1449 1449
        return representation;
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/media/in/MediaExcelImport.java
22 22
import org.joda.time.Partial;
23 23
import org.springframework.stereotype.Component;
24 24

  
25
import eu.etaxonomy.cdm.common.media.ImageInfo;
25
import eu.etaxonomy.cdm.common.media.CdmImageInfo;
26 26
import eu.etaxonomy.cdm.io.common.utils.ImportDeduplicationHelper;
27 27
import eu.etaxonomy.cdm.io.excel.common.ExcelImportBase;
28 28
import eu.etaxonomy.cdm.io.excel.common.ExcelRowBase;
......
223 223
    }
224 224

  
225 225
    private void handleUri(MediaExcelImportState state, URI uri, Media media, String line) {
226
            ImageInfo imageInfo = null;
226
            CdmImageInfo cdmImageInfo = null;
227 227
            try {
228 228
                if (state.getConfig().isReadMediaData()){
229
                    imageInfo = ImageInfo.NewInstance(uri, 0);
229
                    cdmImageInfo = CdmImageInfo.NewInstance(uri, 0);
230 230
                }
231 231
            } catch (Exception e) {
232 232
                String message = "An error occurred when trying to read image meta data for %s. Image was created but without metadata.";
233 233
                message = String.format(message, uri.toString());
234 234
                state.getResult().addException(e, message, null, line);
235 235
            }
236
            ImageFile imageFile = ImageFile.NewInstance(uri, null, imageInfo);
236
            ImageFile imageFile = ImageFile.NewInstance(uri, null, cdmImageInfo);
237 237

  
238 238
            MediaRepresentation representation = MediaRepresentation.NewInstance();
239 239

  
240
            if(imageInfo != null){
241
                representation.setMimeType(imageInfo.getMimeType());
242
                representation.setSuffix(imageInfo.getSuffix());
240
            if(cdmImageInfo != null){
241
                representation.setMimeType(cdmImageInfo.getMimeType());
242
                representation.setSuffix(cdmImageInfo.getSuffix());
243 243
            }
244 244
            representation.addRepresentationPart(imageFile);
245 245
            media.addRepresentation(representation);
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/sdd/in/SDDImport.java
34 34
import org.springframework.transaction.TransactionStatus;
35 35

  
36 36
import eu.etaxonomy.cdm.api.service.IDescriptionService;
37
import eu.etaxonomy.cdm.common.media.ImageInfo;
37
import eu.etaxonomy.cdm.common.media.CdmImageInfo;
38 38
import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
39 39
import eu.etaxonomy.cdm.io.common.ICdmImport;
40 40
import eu.etaxonomy.cdm.io.common.ImportHelper;
......
1592 1592
						Element elSource = elMO.getChild("Source",sddNamespace);
1593 1593
						String href = elSource.getAttributeValue("href");
1594 1594

  
1595
						ImageInfo imageMetaData = null;
1595
						CdmImageInfo imageMetaData = null;
1596 1596
						ImageFile image = null;
1597 1597

  
1598 1598
						if (href.substring(0,7).equals("http://")) {
1599 1599
							try{
1600 1600
								URL url = new URL(href);
1601 1601

  
1602
								imageMetaData = ImageInfo.NewInstance(url.toURI(), 0);
1602
								imageMetaData = CdmImageInfo.NewInstance(url.toURI(), 0);
1603 1603
								image = ImageFile.NewInstance(url.toURI(), null, imageMetaData);
1604 1604
							} catch (MalformedURLException e) {
1605 1605
								logger.error("Malformed URL", e);
......
1612 1612
							File parent = f.getParentFile();
1613 1613
							String fi = parent.toString() + File.separator + href;
1614 1614
							File file = new File(fi);
1615
							imageMetaData = ImageInfo.NewInstance(new URI(fi), 0); //file
1615
							imageMetaData = CdmImageInfo.NewInstance(new URI(fi), 0); //file
1616 1616
							image = ImageFile.NewInstance(file.toURI(), null, imageMetaData);
1617 1617
						}
1618 1618
						MediaRepresentation representation = MediaRepresentation.NewInstance(imageMetaData.getMimeType(), null);
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/media/ImageFile.java
22 22
import org.apache.log4j.Logger;
23 23
import org.hibernate.envers.Audited;
24 24

  
25
import eu.etaxonomy.cdm.common.media.ImageInfo;
25
import eu.etaxonomy.cdm.common.media.CdmImageInfo;
26 26
import eu.etaxonomy.cdm.model.agent.AgentBase;
27 27
import eu.etaxonomy.cdm.model.common.TimePeriod;
28 28

  
......
59 59
		return new ImageFile(uri, size, height, width);
60 60
	}
61 61

  
62
	public static ImageFile NewInstance(URI uri, Integer size, ImageInfo imageInfo){
62
	public static ImageFile NewInstance(URI uri, Integer size, CdmImageInfo cdmImageInfo){
63 63
		ImageFile imageFile = NewInstance(uri, size);
64 64

  
65
		if(imageInfo != null){
66
			imageFile.setHeight(imageInfo.getHeight());
67
			imageFile.setWidth(imageInfo.getWidth());
68
			if(imageInfo.getLength() != 0){
69
			    imageFile.setSize((int)imageInfo.getLength());
65
		if(cdmImageInfo != null){
66
			imageFile.setHeight(cdmImageInfo.getHeight());
67
			imageFile.setWidth(cdmImageInfo.getWidth());
68
			if(cdmImageInfo.getLength() != 0){
69
			    imageFile.setSize((int)cdmImageInfo.getLength());
70 70
			}
71 71
		}
72 72

  
cdmlib-remote/src/main/java/eu/etaxonomy/cdm/remote/controller/MediaController.java
32 32

  
33 33
import eu.etaxonomy.cdm.api.service.IMediaService;
34 34
import eu.etaxonomy.cdm.api.service.MediaServiceImpl;
35
import eu.etaxonomy.cdm.common.media.ImageInfo;
36 35
import eu.etaxonomy.cdm.model.media.Media;
37 36
import eu.etaxonomy.cdm.model.media.MediaRepresentation;
38 37
import eu.etaxonomy.cdm.remote.exception.NoRecordsMatchException;
......
78 77
            MediaRepresentation mediaRepresentation = representations.iterator().next();
79 78
            URI uri = mediaRepresentation.getParts().get(0).getUri();
80 79
            try {
81
                    ImageInfo imageInfo = ImageInfo.NewInstanceWithMetaData(uri, MediaServiceImpl.IMAGE_READ_TIMEOUT);
82
                    result = imageInfo.getMetaData();
80
                    ImageInfo imageInfo = CdmImageInfo.NewInstanceWithMetaData(uri, MediaServiceImpl.IMAGE_READ_TIMEOUT);
81
                    result = cdmImageInfo.getMetaData();
83 82

  
84 83
            } catch (HttpException e) {
85 84
                logger.info(e.getMessage());
cdmlib-remote/src/main/java/eu/etaxonomy/cdm/remote/controller/iiif/ManifestController.java
48 48
import eu.etaxonomy.cdm.api.service.ITermService;
49 49
import eu.etaxonomy.cdm.api.service.MediaServiceImpl;
50 50
import eu.etaxonomy.cdm.api.service.util.TaxonRelationshipEdge;
51
import eu.etaxonomy.cdm.common.media.ImageInfo;
51
import eu.etaxonomy.cdm.common.media.CdmImageInfo;
52 52
import eu.etaxonomy.cdm.model.common.Credit;
53 53
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
54 54
import eu.etaxonomy.cdm.model.common.Language;
......
395 395
            }
396 396
            if (part.getUri() != null) {
397 397
                try {
398
                    ImageInfo imageInfo = ImageInfo.NewInstanceWithMetaData(part.getUri(), MediaServiceImpl.IMAGE_READ_TIMEOUT);
399
                    Map<String, String> result = imageInfo.getMetaData();
398
                    CdmImageInfo cdmImageInfo = CdmImageInfo.NewInstanceWithMetaData(part.getUri(), MediaServiceImpl.IMAGE_READ_TIMEOUT);
399
                    Map<String, String> result = cdmImageInfo.getMetaData();
400 400
                    if(result != null){
401 401
                        for (String key : result.keySet()) {
402 402
                            metadata.add(new MetadataEntry(key, result.get(key)));

Also available in: Unified diff