Subversion Repositories general

Rev

Rev 936 | Rev 1074 | 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;
26
  protected static final int FILTER_TYPE   = Resample.FILTER_TYPE_LANCZOS3;
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
  {
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) {
65
      ex.printStackTrace();
66
 
67
      throw new RuntimeException(ex.getMessage());
68
    }
69
  }
70
 
71
  protected static BufferedImage convertToAwtImage(PixelImage image, int alpha)
72
  {
73
    if (image == null)
74
    {
75
      return null;
76
    }
77
    if (image instanceof RGB24Image)
78
    {
79
      return convertToAwtImage((RGB24Image)image, alpha);
80
    }
81
    else
82
    if (image instanceof Gray8Image)
83
    {
84
      return null; //convertToAwtImage((Gray8Image)image, alpha);
85
    }
86
    else
87
    if (image instanceof Paletted8Image)
88
    {
89
      return null; //convertToAwtImage((Paletted8Image)image, alpha);
90
    }
91
    else
92
    if (image instanceof BilevelImage)
93
    {
94
      return null; //convertToAwtImage((BilevelImage)image, alpha);
95
    }
96
    else
97
    {
98
      return null;
99
    }
100
  }
101
 
102
  protected static BufferedImage convertToAwtImage(RGB24Image image, int alpha)
103
  {
104
    if (image == null)
105
    {
106
      return null;
107
    }
108
 
109
    int width = image.getWidth();
110
    int height = image.getHeight();
111
    if (width < 1 || height < 1)
112
    {
113
      return null;
114
    }
115
 
116
    int[] pixels = new int[width];
117
    byte[] red = new byte[width];
118
    byte[] green = new byte[width];
119
    byte[] blue = new byte[width];
120
 
121
    BufferedImage newImage = new BufferedImage(width, height,
122
      BufferedImage.TYPE_INT_RGB);
123
 
124
    for (int y = 0; y < height; y++)
125
    {
126
      image.getByteSamples(RGBIndex.INDEX_RED, 0, y, width, 1, red, 0);
127
      image.getByteSamples(RGBIndex.INDEX_GREEN, 0, y, width, 1, green, 0);
128
      image.getByteSamples(RGBIndex.INDEX_BLUE, 0, y, width, 1, blue, 0);
129
      convertFromRGB24(red, 0, green, 0, blue, 0, alpha, pixels, 0, width);
130
 
131
      for(int x = 0; x < width; x++)
132
        newImage.setRGB(x, y, pixels[x]);
133
    }
134
 
135
    return newImage;
136
  }
137
 
138
  protected static void convertFromRGB24(
139
    byte[] srcRed, int srcRedOffset,
140
    byte[] srcGreen, int srcGreenOffset,
141
    byte[] srcBlue, int srcBlueOffset,
142
    int alpha,
143
    int[] dest, int destOffset,
144
    int num)
145
  {
146
    while (num-- > 0)
147
    {
148
      dest[destOffset++] =
149
        alpha |
150
        (srcBlue[srcBlueOffset++] & 0xff) |
151
        ((srcGreen[srcGreenOffset++] & 0xff) << 8) |
152
        ((srcRed[srcRedOffset++] & 0xff) << 16);
153
    }
154
  }
155
 
156
  /**
157
   * Creates an {@link RGB24Image} from the argument AWT image instance.
158
   * @param image AWT image object to be converted to a {@link RGB24Image}
159
   * @return a {@link RGB24Image} object holding the
160
   *         image data from the argument image
161
   */
162
  protected static RGB24Image convertImageToRGB24Image(Image image)
163
  {
164
    if (image == null)
165
    {
166
      return null;
167
    }
168
    int width = image.getWidth(null);
169
    int height = image.getHeight(null);
170
    if (width < 1 || height < 1)
171
    {
172
      return null;
173
    }
174
    int[] pixels = new int[width * height];
175
    PixelGrabber pg = new PixelGrabber(
176
      image, 0, 0, width, height, pixels, 0, width);
177
 
178
    try
179
    {
180
      pg.grabPixels();
181
    }
182
    catch (InterruptedException e)
183
    {
184
      return null;
185
    }
186
    if ((pg.getStatus() & ImageObserver.ABORT) != 0)
187
    {
188
      //System.err.println("image fetch aborted or errored");
189
      return null;
190
    }
191
    RGB24Image result = new MemoryRGB24Image(width, height);
192
    int offset = 0;
193
    for (int y = 0; y < height; y++)
194
    {
195
      for (int x = 0; x < width; x++)
196
      {
197
        int pixel = pixels[offset++] & 0xffffff;
198
        result.putSample(RGBIndex.INDEX_RED, x, y, pixel >> 16);
199
        result.putSample(RGBIndex.INDEX_GREEN, x, y, (pixel >> 8) & 0xff);
200
        result.putSample(RGBIndex.INDEX_BLUE, x, y, pixel & 0xff);
201
      }
202
    }
203
    return result;
204
  }
205
}