Subversion Repositories general

Rev

Rev 1074 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
936 dev 1
package ak.photoalbum.images.jiu;
2
 
3
import java.awt.Image;
4
import java.awt.image.BufferedImage;
5
import java.awt.image.PixelGrabber;
6
import java.awt.image.ImageObserver;
7
 
8
import org.apache.log4j.Logger;
9
 
10
import ak.photoalbum.images.ImageResizer;
11
 
12
import net.sourceforge.jiu.data.BilevelImage;
13
import net.sourceforge.jiu.data.Gray8Image;
14
import net.sourceforge.jiu.data.MemoryRGB24Image;
15
import net.sourceforge.jiu.data.Paletted8Image;
16
import net.sourceforge.jiu.data.PixelImage;
17
import net.sourceforge.jiu.data.RGB24Image;
18
import net.sourceforge.jiu.data.RGBIndex;
19
import net.sourceforge.jiu.geometry.Resample;
20
 
21
public class JiuResizer
22
  implements ImageResizer
23
{
24
  protected static final int DEFAULT_ALPHA = 0xff000000;
1074 dev 25
  protected static final int FILTER_TYPE   = Resample.FILTER_TYPE_HERMITE;
936 dev 26
    /*
27
      Possible type          small, ms      medium, ms    quality
28
      -----------------------------------------------------------
29
      FILTER_TYPE_BOX           2.4           3.5         very bad
30
      FILTER_TYPE_TRIANGLE      2.9           5.2
31
      FILTER_TYPE_B_SPLINE      3.6           7.2
32
      FILTER_TYPE_BELL          3.5           6.1
33
      FILTER_TYPE_HERMITE       2.9           5.3
34
      FILTER_TYPE_LANCZOS3      4.7           9.7         the best
35
      FILTER_TYPE_MITCHELL      3.6           7.1
36
    */
37
 
1274 dev 38
  private static final Logger logger =  Logger.getLogger(JiuResizer.class);
936 dev 39
 
40
  public JiuResizer()
41
  {
42
  }
43
 
44
  public BufferedImage resize(Image origin, int newWidth, int newHeight)
45
  {
1074 dev 46
	long timeStart = System.currentTimeMillis();
47
 
936 dev 48
    try {
49
      RGB24Image image    = convertImageToRGB24Image(origin);
50
      Resample   resample;
51
 
52
      if(image == null) return null;
53
      if(image.getWidth() == newWidth && image.getHeight() == newHeight)
54
        return convertToAwtImage(image, DEFAULT_ALPHA);
55
 
56
      resample = new Resample();
57
      resample.setInputImage(image);
58
      resample.setSize(newWidth, newHeight);
59
      resample.setFilter(FILTER_TYPE);
60
      resample.process();
61
 
62
      return convertToAwtImage(resample.getOutputImage(), DEFAULT_ALPHA);
63
    }
64
    catch(Exception ex) {
1274 dev 65
      logger.warn("Cannot resize image", ex);
936 dev 66
 
67
      throw new RuntimeException(ex.getMessage());
68
    }
1074 dev 69
   	finally {
70
      if(logger.isDebugEnabled()) {
71
        logger.debug("resized in " + (System.currentTimeMillis() - timeStart) + " ms");
72
      }
73
    }
936 dev 74
  }
75
 
76
  protected static BufferedImage convertToAwtImage(PixelImage image, int alpha)
77
  {
78
    if (image == null)
79
    {
80
      return null;
81
    }
82
    if (image instanceof RGB24Image)
83
    {
84
      return convertToAwtImage((RGB24Image)image, alpha);
85
    }
86
    else
87
    if (image instanceof Gray8Image)
88
    {
89
      return null; //convertToAwtImage((Gray8Image)image, alpha);
90
    }
91
    else
92
    if (image instanceof Paletted8Image)
93
    {
94
      return null; //convertToAwtImage((Paletted8Image)image, alpha);
95
    }
96
    else
97
    if (image instanceof BilevelImage)
98
    {
99
      return null; //convertToAwtImage((BilevelImage)image, alpha);
100
    }
101
    else
102
    {
103
      return null;
104
    }
105
  }
106
 
107
  protected static BufferedImage convertToAwtImage(RGB24Image image, int alpha)
108
  {
109
    if (image == null)
110
    {
111
      return null;
112
    }
113
 
114
    int width = image.getWidth();
115
    int height = image.getHeight();
116
    if (width < 1 || height < 1)
117
    {
118
      return null;
119
    }
120
 
121
    int[] pixels = new int[width];
122
    byte[] red = new byte[width];
123
    byte[] green = new byte[width];
124
    byte[] blue = new byte[width];
125
 
126
    BufferedImage newImage = new BufferedImage(width, height,
127
      BufferedImage.TYPE_INT_RGB);
128
 
129
    for (int y = 0; y < height; y++)
130
    {
131
      image.getByteSamples(RGBIndex.INDEX_RED, 0, y, width, 1, red, 0);
132
      image.getByteSamples(RGBIndex.INDEX_GREEN, 0, y, width, 1, green, 0);
133
      image.getByteSamples(RGBIndex.INDEX_BLUE, 0, y, width, 1, blue, 0);
134
      convertFromRGB24(red, 0, green, 0, blue, 0, alpha, pixels, 0, width);
135
 
136
      for(int x = 0; x < width; x++)
137
        newImage.setRGB(x, y, pixels[x]);
138
    }
139
 
140
    return newImage;
141
  }
142
 
143
  protected static void convertFromRGB24(
144
    byte[] srcRed, int srcRedOffset,
145
    byte[] srcGreen, int srcGreenOffset,
146
    byte[] srcBlue, int srcBlueOffset,
147
    int alpha,
148
    int[] dest, int destOffset,
149
    int num)
150
  {
151
    while (num-- > 0)
152
    {
153
      dest[destOffset++] =
154
        alpha |
155
        (srcBlue[srcBlueOffset++] & 0xff) |
156
        ((srcGreen[srcGreenOffset++] & 0xff) << 8) |
157
        ((srcRed[srcRedOffset++] & 0xff) << 16);
158
    }
159
  }
160
 
161
  /**
162
   * Creates an {@link RGB24Image} from the argument AWT image instance.
163
   * @param image AWT image object to be converted to a {@link RGB24Image}
164
   * @return a {@link RGB24Image} object holding the
165
   *         image data from the argument image
166
   */
167
  protected static RGB24Image convertImageToRGB24Image(Image image)
168
  {
169
    if (image == null)
170
    {
171
      return null;
172
    }
173
    int width = image.getWidth(null);
174
    int height = image.getHeight(null);
175
    if (width < 1 || height < 1)
176
    {
177
      return null;
178
    }
179
    int[] pixels = new int[width * height];
180
    PixelGrabber pg = new PixelGrabber(
181
      image, 0, 0, width, height, pixels, 0, width);
182
 
183
    try
184
    {
185
      pg.grabPixels();
186
    }
187
    catch (InterruptedException e)
188
    {
189
      return null;
190
    }
191
    if ((pg.getStatus() & ImageObserver.ABORT) != 0)
192
    {
193
      //System.err.println("image fetch aborted or errored");
194
      return null;
195
    }
196
    RGB24Image result = new MemoryRGB24Image(width, height);
197
    int offset = 0;
198
    for (int y = 0; y < height; y++)
199
    {
200
      for (int x = 0; x < width; x++)
201
      {
202
        int pixel = pixels[offset++] & 0xffffff;
203
        result.putSample(RGBIndex.INDEX_RED, x, y, pixel >> 16);
204
        result.putSample(RGBIndex.INDEX_GREEN, x, y, (pixel >> 8) & 0xff);
205
        result.putSample(RGBIndex.INDEX_BLUE, x, y, pixel & 0xff);
206
      }
207
    }
208
    return result;
209
  }
210
}