Subversion Repositories general

Rev

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