texturesynthesis.synthesizer
Class WangTileSynthesizer

java.lang.Object
  extended by texturesynthesis.synthesizer.WangTileSynthesizer
All Implemented Interfaces:
TextureSynthesizer

public class WangTileSynthesizer
extends java.lang.Object
implements TextureSynthesizer

The Wang Tile texture synthesis plugin. For detailed explanation of the algorithm see: Michael F. Cohen, Jonathan Shade, Stefan Hiller, Oliver Deussen: Wang Tiles for Image and Texture Generation. SIGGRAPH 2003, July, 2003 This plugin implements the algorithm with minor changes done by the author. Also some required details of the algorithms weren't explained thoroughly in the paper so these had to be guessed, invented or otherwise generated.

Author:
Aki Koskinen

Field Summary
private static int _EAST
           
private static int _NORTH
           
private static int _SOUTH
           
private static int _WEST
           
private  java.util.Vector<java.awt.Rectangle> horizontalDiamondImages
          Space for images that will form the top and bottom sides of the Wang tiles.
private  int patchSize
          The space in pixels of a patch.
private  WangTileSettings settings
          The settings panel.
private  EditableImage sourceImage
          Source image pixels in an array.
private  java.util.Vector<java.awt.Rectangle> verticalDiamondImages
          Space for images that will form the left and right sides of the Wang tiles.
private  java.util.Vector<EditableImage> wangTileImages
          Space for the Wang tile images.
private  int wangTileSize
          The space in pixels a Wang tile represents.
private  WangTiling wangTiling
          The Wang tiling that generates the image.
 
Constructor Summary
WangTileSynthesizer()
          The constructor.
 
Method Summary
private  java.awt.image.BufferedImage constructImage(WangTiling wangTiling, int width, int height)
          Constructs the actual image from the generated Wang tiles according to the Wang tiling.
private  void createSourceImage(java.awt.Image image)
          Creates a EditableImage of the source image.
private  void fillAreaWithImage(EditableImage source, EditableImage target, int targetX, int targetY, boolean[][] path, int x, int y)
          Helper method for fillPatch().
private  void fillPatch(EditableImage patchImg, EditableImage targetImage, int targetX, int targetY, boolean[][] path, int startX, int startY, int dx, int dy)
          Copies pixels from a source image to target image as long as the path allows.
private  boolean[][] findShortestPath(EditableImage img1, EditableImage img2, int x0, int y0, int x1, int y1)
          Finds the shortest path along two images between two points.
private  void generateDiamondImages(int nHorizontal, int nVertical, int size)
          Generates the diamond shaped images used in the Wang tile synthesis.
private  void generateDiamondImageSet(int n, int size, java.util.Vector<java.awt.Rectangle> set)
          Helper method to generate the diamond images.
 java.awt.Image generateTexture(java.awt.Image image, int width, int height)
          Synthesizes an image of given size from a sample image.
private  void generateWangTileImages(WangTileSet tileSet)
          Generates Wang tile images from the previously generated diamond images.
 java.lang.String getDescription()
          Returns a description about this texture synthesizer.
 java.lang.String getName()
          Returns the name of this texture synthesizer.
 javax.swing.JComponent getSettingsDialog()
          Returns a settings component for this texture synthesizer.
private  void gluePatches(EditableImage targetImage, int targetX, int targetY, java.awt.Rectangle patch1, java.awt.Rectangle patch2, int x0, int y0, int x1, int y1, int patch1Flags, int patch2Flags)
          Copies parts from two source images to the target image.
private  void setWangTileSize(int size)
          Sets the size of the Wang tiles in pixels.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

settings

private WangTileSettings settings
The settings panel.


wangTileSize

private int wangTileSize
The space in pixels a Wang tile represents.


patchSize

private int patchSize
The space in pixels of a patch. This is actually wangTileSize/2. It is just a helper so we don't have to calculate the half wangTileSize all the time.


sourceImage

private EditableImage sourceImage
Source image pixels in an array.


verticalDiamondImages

private java.util.Vector<java.awt.Rectangle> verticalDiamondImages
Space for images that will form the left and right sides of the Wang tiles.


horizontalDiamondImages

private java.util.Vector<java.awt.Rectangle> horizontalDiamondImages
Space for images that will form the top and bottom sides of the Wang tiles.


wangTileImages

private java.util.Vector<EditableImage> wangTileImages
Space for the Wang tile images.


wangTiling

private WangTiling wangTiling
The Wang tiling that generates the image.


_NORTH

private static final int _NORTH
See Also:
Constant Field Values

_EAST

private static final int _EAST
See Also:
Constant Field Values

_SOUTH

private static final int _SOUTH
See Also:
Constant Field Values

_WEST

private static final int _WEST
See Also:
Constant Field Values
Constructor Detail

WangTileSynthesizer

public WangTileSynthesizer()
The constructor. Constructs a new Wang tile texture synthesizer.

Method Detail

setWangTileSize

private void setWangTileSize(int size)
                      throws java.lang.IllegalArgumentException
Sets the size of the Wang tiles in pixels. The size must be positive and even.

Parameters:
size - the new size of the tiles.
Throws:
java.lang.IllegalArgumentException - if the argument is not positive and even.

generateTexture

public java.awt.Image generateTexture(java.awt.Image image,
                                      int width,
                                      int height)
                               throws TextureSynthesizerException
Description copied from interface: TextureSynthesizer
Synthesizes an image of given size from a sample image.

Specified by:
generateTexture in interface TextureSynthesizer
Parameters:
image - the image that is used in the synthesis
width - the width of the synthesized image
height - the height of the synthesized image
Returns:
the synthesized image
Throws:
TextureSynthesizerException
See Also:
TextureSynthesizer.generateTexture(java.awt.Image, int, int)

getName

public java.lang.String getName()
Description copied from interface: TextureSynthesizer
Returns the name of this texture synthesizer.

Specified by:
getName in interface TextureSynthesizer
Returns:
the name of this texture synthesizer.
See Also:
TextureSynthesizer.getName()

getDescription

public java.lang.String getDescription()
Description copied from interface: TextureSynthesizer
Returns a description about this texture synthesizer.

Specified by:
getDescription in interface TextureSynthesizer
Returns:
a description about this texture synthesizer.
See Also:
TextureSynthesizer.getDescription()

getSettingsDialog

public javax.swing.JComponent getSettingsDialog()
Description copied from interface: TextureSynthesizer
Returns a settings component for this texture synthesizer. The settings component should include appropriate widgets for setting the parameters relevant to a specific texture synthesizer.

Specified by:
getSettingsDialog in interface TextureSynthesizer
Returns:
a settings component.
See Also:
TextureSynthesizer.getSettingsDialog()

createSourceImage

private void createSourceImage(java.awt.Image image)
Creates a EditableImage of the source image.

Parameters:
image - the source image

generateDiamondImages

private void generateDiamondImages(int nHorizontal,
                                   int nVertical,
                                   int size)
                            throws TextureSynthesizerException
Generates the diamond shaped images used in the Wang tile synthesis. One diamond image is generated for every edge color. See more from the paper.

Parameters:
nHorizontal - number of colors (and therefore diamond images) in the horizontal direction.
nVertical - number of colors (and therefore diamond images) in the vertical direction.
size - size of the Wang tile images in pixels.
Throws:
TextureSynthesizerException - if the generation is not possible.

generateDiamondImageSet

private void generateDiamondImageSet(int n,
                                     int size,
                                     java.util.Vector<java.awt.Rectangle> set)
                              throws TextureSynthesizerException
Helper method to generate the diamond images.

Parameters:
n - number of diamond images.
size - size of the Wang tile images in pixels.
set - the Vector to put the images in.
Throws:
TextureSynthesizerException - if the generation is not possible.

generateWangTileImages

private void generateWangTileImages(WangTileSet tileSet)
Generates Wang tile images from the previously generated diamond images.

Parameters:
tileSet - the Wang tile set to be used.

gluePatches

private void gluePatches(EditableImage targetImage,
                         int targetX,
                         int targetY,
                         java.awt.Rectangle patch1,
                         java.awt.Rectangle patch2,
                         int x0,
                         int y0,
                         int x1,
                         int y1,
                         int patch1Flags,
                         int patch2Flags)
Copies parts from two source images to the target image. The source images are considered to be on top of each other i.e. of same size and in the same position. The images are blended along a path. The end points of the path are given as parameters. The last two parameters tell which edges of the area should the corresponding images fill. The parameters should be an or'ed value of two of the following constants: _NORTH, _EAST, _SOUTH, _WEST. The constants should also be adjacent in the compass point of sense. E.g. _NORTH and _WEST are adjacent while _NORTH and _SOUTH are not. The parameters should also be mutually exclusive, in other words they should define opposite corners of a square. If patch1Flags is '_NORTH | _WEST', patch2Flags should be '_SOUTH | _EAST'.

Parameters:
targetImage - the target image.
targetX - the vertical offset in the target image.
targetY - the horizontal offset in the target image.
patch1 - the first source image to be used.
patch2 - the second source image to be used.
x0 - x-coordinate of the starting point of the cutting path.
y0 - y-coordinate of the starting point of the cutting path.
x1 - x-coordinate of the end point of the cutting path.
y1 - y-coordinate of the end point of the cutting path.
patch1Flags - fill edges of the first source image.
patch2Flags - fill edges of the second source image.

fillPatch

private void fillPatch(EditableImage patchImg,
                       EditableImage targetImage,
                       int targetX,
                       int targetY,
                       boolean[][] path,
                       int startX,
                       int startY,
                       int dx,
                       int dy)
Copies pixels from a source image to target image as long as the path allows. This is kind of a flood fill. The starting point is actually a line: it is defined by a starting point and a direction.

Parameters:
patchImg - the source image.
targetImage - the target image.
targetX - offset in the vertical direction.
targetY - offset in the horizontal direction.
path - the limiting path.
startX - x-coordinate of the point to start from.
startY - y-coordinate of the point to start from.
dx - vertical direction.
dy - horizontal direction.

findShortestPath

private boolean[][] findShortestPath(EditableImage img1,
                                     EditableImage img2,
                                     int x0,
                                     int y0,
                                     int x1,
                                     int y1)
                              throws java.lang.IllegalArgumentException
Finds the shortest path along two images between two points. This method uses Dijkstra's shortest path algorithm. The path travels along image pixels. The cost of a pixel comes from the distance of the color values of the two images.

Parameters:
img1 - the first image.
img2 - the second image.
x0 - x-coordinate of the start point of the path.
y0 - y-coordinate of the start point of the path.
x1 - x-coordinate of the end point of the path.
y1 - y-coordinate of the end point of the path.
Returns:
the path. True values belong to the path, false values do not.
Throws:
java.lang.IllegalArgumentException - if the images are not of same size.

fillAreaWithImage

private void fillAreaWithImage(EditableImage source,
                               EditableImage target,
                               int targetX,
                               int targetY,
                               boolean[][] path,
                               int x,
                               int y)
Helper method for fillPatch(). Does the actual pixel copying.

Parameters:
source - source image.
target - target image.
targetX - vertical offset in the target image.
targetY - horizontal offset in the target image.
path - the limiting path.
x - start point x-coordinate.
y - start point y-coordinate.

constructImage

private java.awt.image.BufferedImage constructImage(WangTiling wangTiling,
                                                    int width,
                                                    int height)
Constructs the actual image from the generated Wang tiles according to the Wang tiling.

Parameters:
wangTiling - the Wang tiling to be used.
width - the width of the resulting image.
height - the height of the resulting image.
Returns:
the resulting image.