1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.ui.mediaeditor.field.image;
35
36 import info.magnolia.ui.mediaeditor.action.feature.Scalable;
37 import info.magnolia.ui.mediaeditor.field.MediaField;
38
39 import java.awt.image.BufferedImage;
40 import java.io.ByteArrayInputStream;
41 import java.io.ByteArrayOutputStream;
42 import java.io.IOException;
43 import java.io.InputStream;
44 import java.util.Iterator;
45
46 import javax.imageio.ImageIO;
47
48 import org.apache.commons.io.IOUtils;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51
52 import com.vaadin.server.StreamResource;
53 import com.vaadin.server.StreamResource.StreamSource;
54 import com.vaadin.ui.Alignment;
55 import com.vaadin.ui.Component;
56 import com.vaadin.ui.HasComponents;
57 import com.vaadin.ui.Image;
58 import com.vaadin.v7.ui.CustomField;
59 import com.vaadin.v7.ui.VerticalLayout;
60
61
62
63
64 public abstract class ImageMediaField extends CustomField<byte[]> implements MediaField, Scalable {
65 private static final Logger log = LoggerFactory.getLogger(ImageMediaField.class);
66
67 protected final static String DEFAULT_FORMAT = "png";
68
69 protected final static String TEMP_FILE_NAME_BASE = "image_media_editor";
70
71 private Component fieldComponent;
72
73 @Override
74 protected Component initContent() {
75 addStyleName("image-media-field");
76 setSizeFull();
77 VerticalLayout mediaContentWrapper = new VerticalLayout();
78 mediaContentWrapper.addStyleName("media-wrapper");
79 mediaContentWrapper.setSizeFull();
80 fieldComponent = createImage();
81 mediaContentWrapper.addComponent(fieldComponent);
82 mediaContentWrapper.setComponentAlignment(fieldComponent, Alignment.MIDDLE_CENTER);
83 return mediaContentWrapper;
84 }
85
86 protected abstract Component createImage();
87
88 @Override
89 protected void setInternalValue(byte[] newValue) {
90 super.setInternalValue(newValue);
91 if (newValue != null) {
92 refreshImageSource();
93 }
94 }
95
96 @Override
97 public void scaleToActualSize() {
98 doScaleToActual(this);
99 }
100
101 private void doScaleToActual(HasComponents hc) {
102 Iterator<Component> it = hc.iterator();
103 while (it.hasNext()) {
104 Component c = it.next();
105 if (c instanceof Image) {
106 c.removeStyleName("scale-to-fit");
107 } else if (c instanceof HasComponents) {
108 doScaleToActual((HasComponents)c);
109 }
110 }
111 }
112
113 @Override
114 public void scaleToFit() {
115 doScaleToFit(this);
116 }
117
118 private void doScaleToFit(HasComponents hc) {
119 Iterator<Component> it = hc.iterator();
120 while (it.hasNext()) {
121 Component c = it.next();
122 if (c instanceof Image) {
123 c.addStyleName("scale-to-fit");
124 } else if (c instanceof HasComponents) {
125 doScaleToFit((HasComponents)c);
126 }
127 }
128 }
129
130 @Override
131 public Class<byte[]> getType() {
132 return byte[].class;
133 }
134
135 @Override
136 public void applyChanges() {
137 }
138
139 @Override
140 public void revertChanges() {
141 }
142
143 public void execute() {
144 InputStream stream = null;
145 try {
146 BufferedImage result = executeImageModification();
147 stream = createStreamSource(result, DEFAULT_FORMAT);
148 if (result != null) {
149 setValue(IOUtils.toByteArray(stream));
150 refreshImageSource();
151 }
152 } catch (IOException e) {
153 log.error("Error occurred while converting operation result into stream: " + e.getMessage(), e);
154 revertChanges();
155 } finally {
156 IOUtils.closeQuietly(stream);
157 }
158 }
159
160 protected BufferedImage executeImageModification() throws IOException {
161 return null;
162 }
163
164 public abstract void refreshImageSource();
165
166 protected String generateTempFileName() {
167 return TEMP_FILE_NAME_BASE + System.currentTimeMillis();
168 }
169
170 protected StreamResource createResourceFromValue() {
171 return new StreamResource(new StreamSource() {
172 @Override
173 public InputStream getStream() {
174 return new ByteArrayInputStream(getValue());
175 }
176 }, generateTempFileName()) {{
177 setMIMEType("image/" + DEFAULT_FORMAT);
178 }};
179 }
180
181 protected InputStream createStreamSource(final BufferedImage img, final String formatName) throws IOException {
182 ByteArrayOutputStream os = null;
183 try {
184 if (img == null) {
185 return null;
186 }
187 os = new ByteArrayOutputStream();
188 ImageIO.write(img, formatName, os);
189 return new ByteArrayInputStream(os.toByteArray());
190 } finally {
191 IOUtils.closeQuietly(os);
192 }
193 }
194 }