OSDN Git Service

dmg作成バージョンの取得方法の修正
[charactermanaj/CharacterManaJ.git] / src / charactermanaj / graphics / filters / AbstractFilter.java
1 package charactermanaj.graphics.filters;\r
2 \r
3 import java.awt.Rectangle;\r
4 import java.awt.RenderingHints;\r
5 import java.awt.geom.Point2D;\r
6 import java.awt.geom.Rectangle2D;\r
7 import java.awt.image.BufferedImage;\r
8 import java.awt.image.BufferedImageOp;\r
9 import java.awt.image.ColorModel;\r
10 import java.awt.image.DataBufferInt;\r
11 import java.awt.image.WritableRaster;\r
12 \r
13 /**\r
14  * 色フィルタの抽象クラス.<br>\r
15  * @author seraphy\r
16  */\r
17 public abstract class AbstractFilter implements BufferedImageOp {\r
18 \r
19         /**\r
20          * 色変換を行うルーチン.<br>\r
21          * 派生クラスでオーバーライドする.<br>\r
22          * @param pixcels ARGB形式のピクセルデータ\r
23          */\r
24         protected abstract void filter(int[] pixcels);\r
25 \r
26         public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel destCM) {\r
27                 if (destCM == null) {\r
28                         destCM = src.getColorModel();\r
29                 }\r
30                 int w = src.getWidth();\r
31                 int h = src.getHeight();\r
32                 return new BufferedImage(destCM,\r
33                                 destCM.createCompatibleWritableRaster(w, h),\r
34                                 destCM.isAlphaPremultiplied(), null);\r
35         }\r
36 \r
37         public BufferedImage filter(BufferedImage src, BufferedImage dest) {\r
38                 if (dest == null) {\r
39                         dest = createCompatibleDestImage(src, null);\r
40                 }\r
41                 int w = src.getWidth();\r
42                 int h = src.getHeight();\r
43                 \r
44                 int imageType = src.getType();\r
45                 int [] pixcels;\r
46                 boolean shared = false;\r
47                 if (src == dest && (imageType == BufferedImage.TYPE_INT_ARGB || imageType == BufferedImage.TYPE_INT_RGB)) {\r
48                         // 元イメージと出力先イメージが同一であり、且つ、\r
49                         // イメージがARGB/RGB形式であればピクセルデータはイメージが持つバッファそのものを共有アクセスする.\r
50                         // したがって、setPixcelsの呼び出しは不要.\r
51                         pixcels = null;\r
52                         shared = true;\r
53                 } else {\r
54                         // 元イメージと出力先イメージが異なるか、もしくは、\r
55                         // イメージがARGB/RGB形式以外であれば、RGB形式のint配列に変換して処理する.\r
56                         // イメージに書き戻すためにsetPixcelsの呼び出しが必要となる.\r
57                         int len = w * h;\r
58                         pixcels = new int[len];\r
59                 }\r
60                 pixcels = getPixcels(src, 0, 0, w, h, pixcels);\r
61                 \r
62                 filter(pixcels);\r
63 \r
64                 if (!shared) {\r
65                         setPixcels(dest, 0, 0, w, h, pixcels);\r
66                 }\r
67 \r
68                 return dest;\r
69         }\r
70         \r
71 \r
72         public Rectangle2D getBounds2D(BufferedImage src) {\r
73                 int w = src.getWidth();\r
74                 int h = src.getHeight();\r
75                 return new Rectangle(0, 0, w, h);\r
76         }\r
77 \r
78         public Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {\r
79                 return (Point2D) srcPt.clone();\r
80         }\r
81 \r
82         public RenderingHints getRenderingHints() {\r
83                 return null;\r
84         }\r
85 \r
86         /**\r
87          * ピクセルデータを取得する.<br>\r
88          * 画像のタイプがARGBもしくはRGBの場合はpixcelsにnullを指定して格納先を指定しない場合は\r
89          * 格納先を自動的に構築する.<br>\r
90          * そうでない場合はピクセルデータはイメージのピクセルバッファを、そのまま返す.(つまり、変更は即イメージの変更になる.)<br>\r
91          * ARGB,RGB以外のイメージは常に幅x高さ分のRGB(もしくはARGB)を格納できるだけのバッファを指定しなければならない.<br>\r
92          * @param img 対象のイメージ\r
93          * @param x 位置x\r
94          * @param y 位置y\r
95          * @param w 幅\r
96          * @param h 高さ\r
97          * @param pixcels 格納先バッファ、もしくはnull\r
98          * @return ピクセルデータ\r
99          */\r
100         protected int[] getPixcels(BufferedImage img, int x, int y, int w, int h, int[] pixcels) {\r
101                 if (w <= 0 || h <= 0) {\r
102                         return new int[0];\r
103                 }\r
104                 int len = w * h;\r
105                 if (pixcels != null && pixcels.length < len) {\r
106                         throw new IllegalArgumentException("array too short.");\r
107                 }\r
108                 \r
109                 int imageType = img.getType();\r
110                 if (imageType == BufferedImage.TYPE_INT_ARGB || imageType == BufferedImage.TYPE_INT_RGB) {\r
111                         WritableRaster raster = img.getRaster();\r
112                         if (pixcels == null) {\r
113                                 DataBufferInt buf = (DataBufferInt) raster.getDataBuffer();\r
114                                 return buf.getData();\r
115                         }\r
116                         return (int[]) raster.getDataElements(x, y, w, h, pixcels);\r
117                 }\r
118 \r
119                 if (pixcels == null) {\r
120                         throw new IllegalArgumentException("image type error.");\r
121                 }\r
122                 return img.getRGB(x, y, w, h, pixcels, 0, w);\r
123         }\r
124 \r
125         /**\r
126          * ピクセルデータをイメージに書き戻す.<br>\r
127          * ピクセルデータがnullであるか幅または高さが0であれば何もしない.<br>\r
128          * @param img 対象のイメージ\r
129          * @param x 位置x\r
130          * @param y 位置y\r
131          * @param w 幅\r
132          * @param h 高さ\r
133          * @param pixcels ピクセルデータ、nullの場合は何もしない.\r
134          */\r
135         protected void setPixcels(BufferedImage img, int x, int y, int w, int h, int[] pixcels) {\r
136                 int len = w * h;\r
137                 if (pixcels == null || w == 0 || h == 0) {\r
138                         return;\r
139                 }\r
140                 if (pixcels.length < len) {\r
141                         throw new IllegalArgumentException("array too short.");\r
142                 }\r
143                 int imageType = img.getType();\r
144                 if (imageType == BufferedImage.TYPE_INT_ARGB || imageType == BufferedImage.TYPE_INT_RGB) {\r
145                         WritableRaster raster = img.getRaster();\r
146                         raster.setDataElements(x, y, w, h, pixcels);\r
147                         return;\r
148                 }\r
149                 img.setRGB(x, y, w, h, pixcels, 0, w);\r
150         }\r
151         \r
152 }\r