1 | // Copyright 2004-2007 Jean-Francois Poilpret |
2 | // |
3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | // you may not use this file except in compliance with the License. |
5 | // You may obtain a copy of the License at |
6 | // |
7 | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | // |
9 | // Unless required by applicable law or agreed to in writing, software |
10 | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | // See the License for the specific language governing permissions and |
13 | // limitations under the License. |
14 | |
15 | package net.sourceforge.hiveboard.drawing; |
16 | |
17 | import java.awt.AlphaComposite; |
18 | import java.awt.Composite; |
19 | import java.awt.Graphics2D; |
20 | import java.awt.Rectangle; |
21 | import java.awt.image.BufferedImage; |
22 | |
23 | import org.apache.commons.logging.Log; |
24 | import org.apache.commons.logging.LogFactory; |
25 | |
26 | public class ImageToolCompositor implements ImageCompositor |
27 | { |
28 | static final private Log _logger = LogFactory.getLog(ImageToolCompositor.class); |
29 | |
30 | public BufferedImage compose(BufferedImage source, |
31 | BufferedImage dest, |
32 | int xorg, |
33 | int yorg) |
34 | { |
35 | Graphics2D graf = dest.createGraphics(); |
36 | int x = Math.max(0, xorg); |
37 | int y = Math.max(0, yorg); |
38 | if (_logger.isDebugEnabled()) |
39 | { |
40 | _logger.debug( "compose source size=" + source.getWidth() + " x " + |
41 | source.getHeight()); |
42 | _logger.debug( "compose dest size=" + dest.getWidth() + " x " + |
43 | dest.getHeight()); |
44 | _logger.debug("compose drawImage(" + x + ", " + y + ")"); |
45 | } |
46 | graf.drawImage(source, null, x, y); |
47 | graf.dispose(); |
48 | return dest; |
49 | } |
50 | |
51 | public BufferedImage computeUsefulSourceImage( BufferedImage source, |
52 | ImageToolSettings settings, |
53 | int clipWidth, |
54 | int clipHeight) |
55 | { |
56 | Rectangle area = computeArea(source, settings); |
57 | // Calculate the best minimum size of the image |
58 | Rectangle size = area.intersection(new Rectangle(0, 0, clipWidth, clipHeight)); |
59 | // Adjust the origin to which the drawing must be done |
60 | area.x = Math.min(0, area.x); |
61 | area.y = Math.min(0, area.y); |
62 | if (_logger.isDebugEnabled()) |
63 | { |
64 | _logger.debug( "computeUsefulSourceImage area=(" + area.x + |
65 | ", " + area.y + ", " + area.width + " x " + area.height + ")"); |
66 | _logger.debug("computeUsefulSourceImage size=" + size.width + " x " + size.height); |
67 | } |
68 | BufferedImage target = new BufferedImage( size.width, |
69 | size.height, |
70 | BufferedImage.TYPE_4BYTE_ABGR); |
71 | Graphics2D graf = target.createGraphics(); |
72 | |
73 | if (settings.isScaled()) |
74 | { |
75 | if (_logger.isDebugEnabled()) |
76 | { |
77 | _logger.debug( "computeUsefulSourceImage drawImage(" + |
78 | area.x + ", " + area.y + ", " + |
79 | area.width + ", " + area.height + ")"); |
80 | } |
81 | graf.drawImage(source, area.x, area.y, area.width, area.height, null); |
82 | } |
83 | else |
84 | { |
85 | // Just draw from source to target |
86 | if (_logger.isDebugEnabled()) |
87 | { |
88 | _logger.debug( "computeUsefulSourceImage drawImage(" + |
89 | area.x + ", " + area.y + ")"); |
90 | } |
91 | graf.drawImage(source, area.x, area.y, null); |
92 | } |
93 | graf.dispose(); |
94 | |
95 | if (settings.isUserAlpha()) |
96 | { |
97 | BufferedImage image = target; |
98 | target = new BufferedImage(size.width, size.height, BufferedImage.TYPE_4BYTE_ABGR); |
99 | graf = target.createGraphics(); |
100 | float alpha = settings.getAlpha(); |
101 | Composite composite = AlphaComposite.getInstance( |
102 | AlphaComposite.SRC_OVER, alpha); |
103 | graf.setComposite(composite); |
104 | _logger.debug("computeUsefulSourceImage drawImage(0,0) with transparency"); |
105 | graf.drawImage(image, 0, 0, null); |
106 | graf.dispose(); |
107 | } |
108 | return target; |
109 | } |
110 | |
111 | protected Rectangle computeArea(BufferedImage source, |
112 | ImageToolSettings settings) |
113 | { |
114 | Rectangle area = settings.getInsertArea(); |
115 | if (settings.isScaled() && settings.isKeepAspect()) |
116 | { |
117 | // Scale source to fit in target but preserve aspect ratio |
118 | int dstWidth = area.width; |
119 | int dstHeight = area.height; |
120 | int srcWidth = source.getWidth(); |
121 | int srcHeight = source.getHeight(); |
122 | if (srcWidth * dstHeight > srcHeight * dstWidth) |
123 | { |
124 | dstHeight = dstWidth * srcHeight / srcWidth; |
125 | } |
126 | else |
127 | { |
128 | dstWidth = dstHeight * srcWidth / srcHeight; |
129 | } |
130 | area.setSize(dstWidth, dstHeight); |
131 | } |
132 | return area; |
133 | } |
134 | } |