Project

General

Profile

Download (6.53 KB) Statistics
| Branch: | Tag: | Revision:
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.lang3.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.CdmUtils;
29
import eu.etaxonomy.cdm.common.UriUtils;
30

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

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

    
44
	private Map<String, String> metaData;
45

    
46
//********************** Factory Methods ******************************/
47

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

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

    
59
		instance.readMetaData(timeOut);
60

    
61
		return instance;
62
	}
63

    
64
//*********************** CONSTRUCTOR **************************************/
65

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

    
70
//*************************** GETTER /SETTER *******************************/
71

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

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

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

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

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

    
92
//**************************** METHODS *****************************/
93

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

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

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

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

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

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

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

    
147

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

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

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

    
161
			if (mediaData != null){
162
				metaData = new HashMap<>();
163
				for (ImageMetadataItem imItem : mediaData.getItems()){
164
					if (imItem instanceof GenericImageMetadataItem){
165
					    GenericImageMetadataItem item = (GenericImageMetadataItem)imItem;
166
					    if ("Keywords".equals(item.getKeyword())){
167
					        String value = text(item);
168
					        String[] splits = value.split(":");
169
	                        if (splits.length == 2){
170
	                            //convention used e.g. for Flora of cyprus (#9137)
171
	                            metaData.put(splits[0].trim(), splits[1].trim());
172
	                        }else{
173
	                            metaData.put(item.getKeyword(), CdmUtils.concat("; ", metaData.get(item.getKeyword()), value));
174
	                        }
175
					    }else if (item.getKeyword().contains("/")){
176
	                        //TODO: not sure where this syntax is used originally
177
					        String key = item.getKeyword();
178
					        //key.replace("/", "");
179
					        int index = key.indexOf("/");
180
					        key = key.substring(0, index);
181
					        metaData.put(key, text(item));
182
					    }else{
183
					        metaData.put(item.getKeyword(), text(item));
184
					    }
185
					}
186
				}
187
			}
188
		}catch (ImageReadException e) {
189
			logger.error("Could not read: " + imageUri + ". " + e.getMessage());
190
			//throw new IOException(e);
191
		}
192
		return metaData;
193
	}
194

    
195
    /**
196
     * Wrapper for the Item.getText() method which applies cleaning of the text representation.
197
     *
198
     * <ol>
199
     * <li>Strings are surrounded by single quotes, these must be removed</li>
200
     * </ol>
201
     * @param item
202
     */
203
    private String text(GenericImageMetadataItem item) {
204
        String  text = item.getText();
205
        if(text.startsWith("'") && text.endsWith("'")) {
206
            text = text.substring(1 , text.length() - 1);
207
        }
208
        return text;
209
    }
210

    
211
// ******************* TO STRING **********************************/
212

    
213
	@Override
214
	public String toString(){
215
        return getFormatName() + " [" + getMimeType()+ "] w:" + width + " h:" + height + " depth:" + bitPerPixel;
216
	}
217
}
(2-2/4)