3434import java .awt .Graphics2D ;
3535import java .awt .RenderingHints .Key ;
3636import java .awt .image .BufferedImage ;
37+ import java .awt .image .ColorModel ;
3738import java .awt .image .ComponentColorModel ;
3839import java .awt .image .DirectColorModel ;
3940import java .awt .image .IndexColorModel ;
5556
5657/**
5758 * A rasterizer implementation for converting SVG data into rasterized images.
58- * This class implements the {@code SVGRasterizer} interface.
59+ * This class uses the third party library JSVG for the raterization of SVG
60+ * images.
5961 *
6062 * @since 1.0.0
6163 */
6264public class JSVGRasterizer implements SVGRasterizer {
6365
6466 private static final SVGLoader SVG_LOADER = new SVGLoader ();
6567
66- private final static Map <Key , Object > RENDERING_HINTS = Map .of (
67- KEY_ANTIALIASING , VALUE_ANTIALIAS_ON , //
68+ private final static Map <Key , Object > RENDERING_HINTS = Map .of (KEY_ANTIALIASING , VALUE_ANTIALIAS_ON , //
6869 KEY_ALPHA_INTERPOLATION , VALUE_ALPHA_INTERPOLATION_QUALITY , //
6970 KEY_COLOR_RENDERING , VALUE_COLOR_RENDER_QUALITY , //
7071 KEY_DITHERING , VALUE_DITHER_DISABLE , //
@@ -76,90 +77,139 @@ public class JSVGRasterizer implements SVGRasterizer {
7677 );
7778
7879 @ Override
79- public ImageData [] rasterizeSVG (InputStream stream , int zoom ) throws IOException {
80- SVGDocument svgDocument = null ;
81- svgDocument = SVG_LOADER .load (stream , null , LoaderContext .createDefault ());
80+ public ImageData [] rasterizeSVG (InputStream inputStream , int zoom ) throws IOException {
81+ SVGDocument svgDocument = loadSVG (inputStream );
8282 if (svgDocument != null ) {
83- float scalingFactor = zoom / 100.0f ;
84- FloatSize size = svgDocument .size ();
85- double originalWidth = size .getWidth ();
86- double originalHeight = size .getHeight ();
87- int scaledWidth = (int ) Math .round (originalWidth * scalingFactor );
88- int scaledHeight = (int ) Math .round (originalHeight * scalingFactor );
89- BufferedImage image = new BufferedImage (scaledWidth , scaledHeight , BufferedImage .TYPE_INT_ARGB );
90- Graphics2D g = image .createGraphics ();
91- g .setRenderingHints (RENDERING_HINTS );
92- g .scale (scalingFactor , scalingFactor );
93- svgDocument .render (null , g );
94- g .dispose ();
95- return new ImageData [] { convertToSWT (image ) };
83+ return generateRasterizedImageData (svgDocument , zoom );
9684 } else {
9785 SWT .error (SWT .ERROR_INVALID_IMAGE );
9886 }
9987 return null ;
10088 }
10189
102- private ImageData convertToSWT (BufferedImage bufferedImage ) {
103- if (bufferedImage .getColorModel () instanceof DirectColorModel ) {
104- DirectColorModel colorModel = (DirectColorModel ) bufferedImage .getColorModel ();
105- PaletteData palette = new PaletteData (colorModel .getRedMask (), colorModel .getGreenMask (),
106- colorModel .getBlueMask ());
107- ImageData data = new ImageData (bufferedImage .getWidth (), bufferedImage .getHeight (),
108- colorModel .getPixelSize (), palette );
109- for (int y = 0 ; y < data .height ; y ++) {
110- for (int x = 0 ; x < data .width ; x ++) {
111- int rgb = bufferedImage .getRGB (x , y );
112- int pixel = palette .getPixel (new RGB ((rgb >> 16 ) & 0xFF , (rgb >> 8 ) & 0xFF , rgb & 0xFF ));
113- data .setPixel (x , y , pixel );
114- if (colorModel .hasAlpha ()) {
115- data .setAlpha (x , y , (rgb >> 24 ) & 0xFF );
116- }
90+ private SVGDocument loadSVG (InputStream inputStream ) {
91+ return SVG_LOADER .load (inputStream , null , LoaderContext .createDefault ());
92+ }
93+
94+ private ImageData [] generateRasterizedImageData (SVGDocument svgDocument , int zoom ) {
95+ BufferedImage rasterizedImage = renderSVG (svgDocument , zoom );
96+ ImageData [] rasterizedImageData = transformtoSWTImageData (rasterizedImage );
97+ return rasterizedImageData ;
98+ }
99+
100+ private BufferedImage renderSVG (SVGDocument svgDocument , int zoom ) {
101+ float scalingFactor = zoom / 100.0f ;
102+ BufferedImage image = createImageBase (svgDocument , scalingFactor );
103+ Graphics2D g = configureRenderingOptions (scalingFactor , image );
104+ svgDocument .render (null , g );
105+ g .dispose ();
106+ return image ;
107+ }
108+
109+ private BufferedImage createImageBase (SVGDocument svgDocument , float scalingFactor ) {
110+ FloatSize sourceImageSize = svgDocument .size ();
111+ int targetImageWidth = calculateTargetWidth (scalingFactor , sourceImageSize );
112+ int targetImageHeight = calculateTargetHeight (scalingFactor , sourceImageSize );
113+ BufferedImage image = new BufferedImage (targetImageWidth , targetImageHeight , BufferedImage .TYPE_INT_ARGB );
114+ return image ;
115+ }
116+
117+ private int calculateTargetWidth (float scalingFactor , FloatSize sourceImageSize ) {
118+ double sourceImageWidth = sourceImageSize .getWidth ();
119+ int targetImageWidth = (int ) Math .round (sourceImageWidth * scalingFactor );
120+ return targetImageWidth ;
121+ }
122+
123+ private int calculateTargetHeight (float scalingFactor , FloatSize sourceImageSize ) {
124+ double sourceImageHeight = sourceImageSize .getHeight ();
125+ int targetImageHeight = (int ) Math .round (sourceImageHeight * scalingFactor );
126+ return targetImageHeight ;
127+ }
128+
129+ private Graphics2D configureRenderingOptions (float scalingFactor , BufferedImage image ) {
130+ Graphics2D g = image .createGraphics ();
131+ g .setRenderingHints (RENDERING_HINTS );
132+ g .scale (scalingFactor , scalingFactor );
133+ return g ;
134+ }
135+
136+ private ImageData [] transformtoSWTImageData (BufferedImage bufferedImage ) {
137+ ColorModel colorModel = bufferedImage .getColorModel ();
138+ if (colorModel instanceof DirectColorModel directColorModel ) {
139+ return generateSWTImageData (bufferedImage , directColorModel );
140+ } else if (colorModel instanceof IndexColorModel indexColorModel ) {
141+ return generateSWTImageData (bufferedImage , indexColorModel );
142+ } else if (colorModel instanceof ComponentColorModel componentColorModel ) {
143+ return generateSWTImageData (bufferedImage , componentColorModel );
144+ }
145+ return null ;
146+ }
147+
148+ private ImageData [] generateSWTImageData (BufferedImage bufferedImage , DirectColorModel colorModel ) {
149+ PaletteData paletteData = new PaletteData (colorModel .getRedMask (), colorModel .getGreenMask (),
150+ colorModel .getBlueMask ());
151+ ImageData imageData = new ImageData (bufferedImage .getWidth (), bufferedImage .getHeight (),
152+ colorModel .getPixelSize (), paletteData );
153+ for (int y = 0 ; y < imageData .height ; y ++) {
154+ for (int x = 0 ; x < imageData .width ; x ++) {
155+ int rgb = bufferedImage .getRGB (x , y );
156+ int pixel = paletteData .getPixel (new RGB ((rgb >> 16 ) & 0xFF , (rgb >> 8 ) & 0xFF , rgb & 0xFF ));
157+ imageData .setPixel (x , y , pixel );
158+ if (colorModel .hasAlpha ()) {
159+ imageData .setAlpha (x , y , (rgb >> 24 ) & 0xFF );
117160 }
118161 }
119- return data ;
120- } else if (bufferedImage .getColorModel () instanceof IndexColorModel ) {
121- IndexColorModel colorModel = (IndexColorModel ) bufferedImage .getColorModel ();
122- int size = colorModel .getMapSize ();
123- byte [] reds = new byte [size ];
124- byte [] greens = new byte [size ];
125- byte [] blues = new byte [size ];
126- colorModel .getReds (reds );
127- colorModel .getGreens (greens );
128- colorModel .getBlues (blues );
129- RGB [] rgbs = new RGB [size ];
130- for (int i = 0 ; i < rgbs .length ; i ++) {
131- rgbs [i ] = new RGB (reds [i ] & 0xFF , greens [i ] & 0xFF , blues [i ] & 0xFF );
132- }
133- PaletteData palette = new PaletteData (rgbs );
134- ImageData data = new ImageData (bufferedImage .getWidth (), bufferedImage .getHeight (),
135- colorModel .getPixelSize (), palette );
136- data .transparentPixel = colorModel .getTransparentPixel ();
137- WritableRaster raster = bufferedImage .getRaster ();
138- int [] pixelArray = new int [1 ];
139- for (int y = 0 ; y < data .height ; y ++) {
140- for (int x = 0 ; x < data .width ; x ++) {
141- raster .getPixel (x , y , pixelArray );
142- data .setPixel (x , y , pixelArray [0 ]);
143- }
162+ }
163+ return new ImageData [] { imageData };
164+ }
165+
166+
167+ private ImageData [] generateSWTImageData (BufferedImage bufferedImage , IndexColorModel indexColorModel ) {
168+ RGB [] colors = calculateColors (indexColorModel );
169+ PaletteData paletteData = new PaletteData (colors );
170+ ImageData imageData = new ImageData (bufferedImage .getWidth (), bufferedImage .getHeight (),
171+ indexColorModel .getPixelSize (), paletteData );
172+ imageData .transparentPixel = indexColorModel .getTransparentPixel ();
173+ WritableRaster raster = bufferedImage .getRaster ();
174+ int [] pixelArray = new int [1 ];
175+ for (int y = 0 ; y < imageData .height ; y ++) {
176+ for (int x = 0 ; x < imageData .width ; x ++) {
177+ raster .getPixel (x , y , pixelArray );
178+ imageData .setPixel (x , y , pixelArray [0 ]);
144179 }
145- return data ;
146- } else if (bufferedImage .getColorModel () instanceof ComponentColorModel ) {
147- ComponentColorModel colorModel = (ComponentColorModel ) bufferedImage .getColorModel ();
148- PaletteData palette = new PaletteData (0x0000FF , 0x00FF00 , 0xFF0000 );
149- ImageData data = new ImageData (bufferedImage .getWidth (), bufferedImage .getHeight (),
150- colorModel .getPixelSize (), palette );
151- data .transparentPixel = -1 ;
152- WritableRaster raster = bufferedImage .getRaster ();
153- int [] pixelArray = new int [3 ];
154- for (int y = 0 ; y < data .height ; y ++) {
155- for (int x = 0 ; x < data .width ; x ++) {
156- raster .getPixel (x , y , pixelArray );
157- int pixel = palette .getPixel (new RGB (pixelArray [0 ], pixelArray [1 ], pixelArray [2 ]));
158- data .setPixel (x , y , pixel );
159- }
180+ }
181+ return new ImageData [] { imageData };
182+ }
183+
184+ private RGB [] calculateColors (IndexColorModel indexColorModel ) {
185+ int size = indexColorModel .getMapSize ();
186+ byte [] reds = new byte [size ];
187+ byte [] greens = new byte [size ];
188+ byte [] blues = new byte [size ];
189+ indexColorModel .getReds (reds );
190+ indexColorModel .getGreens (greens );
191+ indexColorModel .getBlues (blues );
192+ RGB [] rgbs = new RGB [size ];
193+ for (int i = 0 ; i < rgbs .length ; i ++) {
194+ rgbs [i ] = new RGB (reds [i ] & 0xFF , greens [i ] & 0xFF , blues [i ] & 0xFF );
195+ }
196+ return rgbs ;
197+ }
198+
199+ private ImageData [] generateSWTImageData (BufferedImage bufferedImage , ComponentColorModel componentColorModel ) {
200+ PaletteData paletteData = new PaletteData (0x0000FF , 0x00FF00 , 0xFF0000 );
201+ ImageData imageData = new ImageData (bufferedImage .getWidth (), bufferedImage .getHeight (),
202+ componentColorModel .getPixelSize (), paletteData );
203+ imageData .transparentPixel = -1 ;
204+ WritableRaster raster = bufferedImage .getRaster ();
205+ int [] pixelArray = new int [3 ];
206+ for (int y = 0 ; y < imageData .height ; y ++) {
207+ for (int x = 0 ; x < imageData .width ; x ++) {
208+ raster .getPixel (x , y , pixelArray );
209+ int pixel = paletteData .getPixel (new RGB (pixelArray [0 ], pixelArray [1 ], pixelArray [2 ]));
210+ imageData .setPixel (x , y , pixel );
160211 }
161- return data ;
162212 }
163- return null ;
213+ return new ImageData [] { imageData } ;
164214 }
165215}
0 commit comments