543
|
1 /** Worker (Callable) that renders an image.
|
|
2 *
|
|
3 */
|
557
|
4 package digilib.image;
|
543
|
5
|
|
6 import java.awt.Rectangle;
|
|
7 import java.io.IOException;
|
|
8 import java.util.concurrent.Callable;
|
|
9
|
|
10 import org.apache.log4j.Logger;
|
|
11
|
|
12 import digilib.io.FileOpException;
|
557
|
13 import digilib.servlet.DigilibConfiguration;
|
543
|
14
|
|
15 /** Worker that renders an image.
|
|
16 *
|
|
17 * @author casties
|
|
18 *
|
|
19 */
|
|
20 public class ImageWorker implements Callable<DocuImage> {
|
|
21
|
|
22
|
|
23 protected static Logger logger = Logger.getLogger(ImageWorker.class);
|
|
24 private DigilibConfiguration dlConfig;
|
547
|
25 private ImageJobDescription jobinfo;
|
543
|
26
|
547
|
27 public ImageWorker(DigilibConfiguration dlConfig, ImageJobDescription jobinfo) {
|
543
|
28 super();
|
|
29 this.dlConfig = dlConfig;
|
|
30 this.jobinfo = jobinfo;
|
|
31 }
|
|
32
|
|
33 /**
|
|
34 * render and return the image
|
|
35 */
|
|
36 public DocuImage call() throws FileOpException, IOException, ImageOpException {
|
|
37
|
|
38 logger.debug("image worker starting");
|
|
39 long startTime = System.currentTimeMillis();
|
|
40
|
|
41 /* crop and scale image */
|
|
42
|
|
43 // new DocuImage instance
|
564
|
44 DocuImage docuImage = DigilibConfiguration.getDocuImageInstance();
|
543
|
45 if (docuImage == null) {
|
|
46 throw new ImageOpException("Unable to load DocuImage class!");
|
|
47 }
|
|
48
|
|
49 // set interpolation quality
|
565
|
50 docuImage.setQuality(jobinfo.getScaleQual());
|
543
|
51
|
547
|
52 Rectangle loadRect = jobinfo.getOuterUserImgArea().getBounds();
|
|
53 float scaleXY = jobinfo.getScaleXY();
|
543
|
54
|
|
55 // use subimage loading if possible
|
|
56 if (docuImage.isSubimageSupported()) {
|
|
57 logger.debug("Subimage: scale " + scaleXY + " = " + (1 / scaleXY));
|
|
58 float subf = 1f;
|
|
59 float subsamp = 1f;
|
|
60 if (scaleXY < 1) {
|
|
61 subf = 1 / scaleXY;
|
|
62 // for higher quality reduce subsample factor by minSubsample
|
565
|
63 if (jobinfo.getScaleQual() > 0) {
|
543
|
64 subsamp = (float) Math.max(Math.floor(subf / dlConfig.getAsFloat("subsample-minimum")), 1d);
|
|
65 } else {
|
|
66 subsamp = (float) Math.floor(subf);
|
|
67 }
|
|
68 scaleXY = subsamp / subf;
|
|
69 logger.debug("Using subsampling: " + subsamp + " rest "
|
|
70 + scaleXY);
|
|
71 }
|
|
72
|
547
|
73 docuImage.loadSubimage(jobinfo.getFileToLoad(), loadRect, (int) subsamp);
|
543
|
74
|
570
|
75 logger.debug("SUBSAMP: " + subsamp + " -> " + docuImage.getSize());
|
543
|
76
|
|
77 docuImage.scale(scaleXY, scaleXY);
|
|
78
|
|
79 } else {
|
|
80 // else load and crop the whole file
|
547
|
81 docuImage.loadImage(jobinfo.getFileToLoad());
|
543
|
82 docuImage.crop((int) loadRect.getX(), (int) loadRect.getY(),
|
|
83 (int) loadRect.getWidth(), (int) loadRect.getHeight());
|
|
84
|
|
85 docuImage.scale(scaleXY, scaleXY);
|
|
86 }
|
|
87
|
|
88 // mirror image
|
|
89 // operation mode: "hmir": mirror horizontally, "vmir": mirror
|
|
90 // vertically
|
547
|
91 if (jobinfo.hasOption("hmir")) {
|
543
|
92 docuImage.mirror(0);
|
|
93 }
|
547
|
94 if (jobinfo.hasOption("vmir")) {
|
543
|
95 docuImage.mirror(90);
|
|
96 }
|
|
97
|
|
98 // rotate image
|
547
|
99 if (jobinfo.getAsFloat("rot") != 0d) {
|
|
100 docuImage.rotate(jobinfo.getAsFloat("rot"));
|
|
101 /* if (jobinfo.get_wholeRotArea()) {
|
543
|
102 // crop to the inner bounding box
|
|
103 float xcrop = (float) (docuImage.getWidth() - jobinfo.get_innerUserImgArea().getWidth()
|
|
104 * scaleXY);
|
|
105 float ycrop = (float) (docuImage.getHeight() - jobinfo.get_innerUserImgArea().getHeight()
|
|
106 * scaleXY);
|
|
107 if ((xcrop > 0) || (ycrop > 0)) {
|
|
108 // only crop smaller
|
|
109 xcrop = (xcrop > 0) ? xcrop : 0;
|
|
110 ycrop = (ycrop > 0) ? ycrop : 0;
|
|
111 // crop image
|
|
112 docuImage.crop((int) (xcrop / 2), (int) (ycrop / 2),
|
|
113 (int) (docuImage.getWidth() - xcrop),
|
|
114 (int) (docuImage.getHeight() - ycrop));
|
|
115 }
|
547
|
116 } */
|
543
|
117
|
|
118 }
|
|
119
|
|
120 // color modification
|
547
|
121 float[] paramRGBM = jobinfo.getRGBM();
|
|
122 float[] paramRGBA = jobinfo.getRGBA();
|
543
|
123 if ((paramRGBM != null) || (paramRGBA != null)) {
|
547
|
124 // make sure we actually have two arrays
|
543
|
125 if (paramRGBM == null) {
|
|
126 paramRGBM = new float[3];
|
|
127 }
|
|
128 if (paramRGBA == null) {
|
|
129 paramRGBA = new float[3];
|
|
130 }
|
|
131 // calculate "contrast" values (c=2^x)
|
|
132 float[] mult = new float[3];
|
|
133 for (int i = 0; i < 3; i++) {
|
|
134 mult[i] = (float) Math.pow(2, (float) paramRGBM[i]);
|
|
135 }
|
|
136 docuImage.enhanceRGB(mult, paramRGBA);
|
|
137 }
|
|
138
|
|
139 // contrast and brightness enhancement
|
547
|
140 float paramCONT = jobinfo.getAsFloat("cont");
|
|
141 float paramBRGT = jobinfo.getAsFloat("brgt");
|
543
|
142 if ((paramCONT != 0f) || (paramBRGT != 0f)) {
|
|
143 float mult = (float) Math.pow(2, paramCONT);
|
|
144 docuImage.enhance(mult, paramBRGT);
|
|
145 }
|
|
146
|
|
147 logger.debug("rendered in " + (System.currentTimeMillis() - startTime) + "ms");
|
|
148
|
|
149 return docuImage;
|
|
150 }
|
|
151
|
|
152 }
|