Revision 3f04dd4e
Added by Andreas Kohlbecker almost 3 years ago
cdmlib-commons/src/main/java/eu/etaxonomy/cdm/common/media/CdmImageInfo.java | ||
---|---|---|
8 | 8 |
*/ |
9 | 9 |
package eu.etaxonomy.cdm.common.media; |
10 | 10 |
|
11 |
import java.io.IOException; |
|
12 |
import java.io.InputStream; |
|
13 | 11 |
import java.util.HashMap; |
14 | 12 |
import java.util.Map; |
15 | 13 |
|
16 |
import org.apache.commons.imaging.ImageInfo; |
|
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.lang3.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.CdmUtils; |
|
28 | 14 |
import eu.etaxonomy.cdm.common.URI; |
29 |
import eu.etaxonomy.cdm.common.UriUtils; |
|
15 |
|
|
30 | 16 |
|
31 | 17 |
/** |
32 | 18 |
* @author k.luther |
... | ... | |
34 | 20 |
* @since 27.11.2009 |
35 | 21 |
*/ |
36 | 22 |
public class CdmImageInfo extends MediaInfo { |
37 |
private static Logger logger = Logger.getLogger(CdmImageInfo.class); |
|
38 | 23 |
|
39 | 24 |
private int width; |
40 | 25 |
private int height; |
41 | 26 |
private int bitPerPixel; |
42 | 27 |
private final URI imageUri; |
43 | 28 |
|
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 |
} |
|
29 |
private Map<String, String> metaData = new HashMap<>(); |
|
55 | 30 |
|
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 | 31 |
|
64 | 32 |
//*********************** CONSTRUCTOR **************************************/ |
65 | 33 |
|
66 |
private CdmImageInfo(URI imageUri){
|
|
34 |
public CdmImageInfo(URI imageUri){
|
|
67 | 35 |
this.imageUri = imageUri; |
68 | 36 |
} |
69 | 37 |
|
... | ... | |
77 | 45 |
return width; |
78 | 46 |
} |
79 | 47 |
|
80 |
public int getHeight() { |
|
48 |
public void setWidth(int width) { |
|
49 |
this.width = width; |
|
50 |
} |
|
51 |
|
|
52 |
public void setHeight(int height) { |
|
53 |
this.height = height; |
|
54 |
} |
|
55 |
|
|
56 |
public void setBitPerPixel(int bitPerPixel) { |
|
57 |
this.bitPerPixel = bitPerPixel; |
|
58 |
} |
|
59 |
|
|
60 |
public int getHeight() { |
|
81 | 61 |
return height; |
82 | 62 |
} |
83 | 63 |
|
... | ... | |
89 | 69 |
return metaData; |
90 | 70 |
} |
91 | 71 |
|
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 | 72 |
|
211 | 73 |
// ******************* TO STRING **********************************/ |
212 | 74 |
|
Also available in: Unified diff
ref #9607 replacing class local factory methods and heplers in CdmImageInfo by service layer factory classes and metadata 'reader' class