From 0b24d5b71c19ba38060297084ad39685f76a8539 Mon Sep 17 00:00:00 2001 From: gotty Date: Sat, 27 Apr 2019 21:43:58 +0300 Subject: [PATCH] [LIB-9] Add functional for transcoding vector images --- chesshog-graphics/pom.xml | 9 ++ .../hedgecode/chess/img/AbstractImageLoader.java | 24 ++++-- .../main/java/org/hedgecode/chess/img/Diagram.java | 2 +- .../org/hedgecode/chess/img/DiagramBuilder.java | 8 +- .../org/hedgecode/chess/img/FilenameUtils.java | 4 +- .../java/org/hedgecode/chess/img/ImageBuilder.java | 2 +- .../org/hedgecode/chess/img/ImageConstants.java | 1 + .../org/hedgecode/chess/img/ImageException.java | 4 +- .../java/org/hedgecode/chess/img/ImageFilter.java | 3 +- .../java/org/hedgecode/chess/img/ImageFormat.java | 50 +++++------ .../org/hedgecode/chess/img/ImageFormatShaper.java | 69 +++++++++++++++ .../java/org/hedgecode/chess/img/ImageLoader.java | 2 +- .../java/org/hedgecode/chess/img/ImageShaper.java | 37 +++++++++ .../chess/img/bitmap/BitmapImageShaper.java | 95 +++++++++++++++++++++ .../java/org/hedgecode/chess/img/board/Board.java | 24 +++++- .../org/hedgecode/chess/img/board/BoardLoader.java | 36 ++++---- .../org/hedgecode/chess/img/board/SquarePair.java | 11 ++- .../chess/img/fs/DefFileSystemContractor.java | 2 +- .../chess/img/fs/FileSystemContractor.java | 3 +- .../hedgecode/chess/img/fs/FileSystemDetector.java | 2 +- .../chess/img/fs/JarFileSystemContractor.java | 2 +- .../org/hedgecode/chess/img/piece/PieceSet.java | 6 +- .../hedgecode/chess/img/piece/PieceSetLoader.java | 11 +-- .../chess/img/vector/SquareImageTranscoder.java | 97 ++++++++++++++++++++++ .../chess/img/vector/VectorImageShaper.java | 81 ++++++++++++++++++ .../hedgecode/chess/img/LocalStrings.properties | 5 ++ .../hedgecode/chess/img/LocalStrings_ru.properties | 5 ++ 27 files changed, 520 insertions(+), 75 deletions(-) create mode 100644 chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageFormatShaper.java create mode 100644 chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageShaper.java create mode 100644 chesshog-graphics/src/main/java/org/hedgecode/chess/img/bitmap/BitmapImageShaper.java create mode 100644 chesshog-graphics/src/main/java/org/hedgecode/chess/img/vector/SquareImageTranscoder.java create mode 100644 chesshog-graphics/src/main/java/org/hedgecode/chess/img/vector/VectorImageShaper.java diff --git a/chesshog-graphics/pom.xml b/chesshog-graphics/pom.xml index 296bf2d..032e849 100644 --- a/chesshog-graphics/pom.xml +++ b/chesshog-graphics/pom.xml @@ -36,6 +36,10 @@ Hedgecode ChessHog Graphics Module. + + 1.11 + + org.hedgecode.chess @@ -47,6 +51,11 @@ chesshog-format ${chessHogVersion} + + org.apache.xmlgraphics + batik-transcoder + ${transcoderVersion} + \ No newline at end of file diff --git a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/AbstractImageLoader.java b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/AbstractImageLoader.java index c9c4f04..0d3681f 100644 --- a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/AbstractImageLoader.java +++ b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/AbstractImageLoader.java @@ -25,8 +25,6 @@ import java.nio.file.Path; import java.util.HashMap; import java.util.Map; -import javax.imageio.ImageIO; - import org.hedgecode.chess.img.fs.FileSystemDetector; import org.hedgecode.chess.img.fs.FileSystemContractor; @@ -40,6 +38,8 @@ public abstract class AbstractImageLoader implements ImageLoader { private static final String IMAGES_DIR = ImageConstants.RESOURCE_ROOT_DIR.concat(ImageConstants.RESOURCE_IMAGES_DIR); + private static final int DEF_IMAGE_SIZE = 100; + private Type loadType; private URI imageResourceUri; @@ -82,6 +82,12 @@ public abstract class AbstractImageLoader implements ImageLoader { protected Map loadImages(String imagesPath, ImageFilter filter) throws ImageException { + return loadImages(imagesPath, filter, DEF_IMAGE_SIZE); + } + + protected Map loadImages(String imagesPath, ImageFilter filter, int size) + throws ImageException + { Map images = new HashMap<>(); try (FileSystemContractor fsc = FileSystemDetector.detect(getImageResourceUri())) { try (DirectoryStream ds = @@ -89,13 +95,17 @@ public abstract class AbstractImageLoader implements ImageLoader { fsc.getPath(imagesPath), filter ) ) { + ImageFormatShaper formatShaper = ImageFormatShaper.getInstance(); for (Path file : ds) { + String fileName = file.getFileName().toString(); + String baseName = FilenameUtils.getBaseName(fileName).toLowerCase(); + String imageFormat = FilenameUtils.getExtension(fileName).toLowerCase(); images.put( - FilenameUtils.getBaseName( - file.getFileName().toString() - ).toLowerCase(), - ImageIO.read( - fsc.getResourceAsStream(file) + baseName, + formatShaper.shape( + imageFormat, + fsc.getResourceAsStream(file), + size ) ); } diff --git a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/Diagram.java b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/Diagram.java index 05b6381..6d62d86 100644 --- a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/Diagram.java +++ b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/Diagram.java @@ -21,7 +21,7 @@ import java.awt.image.RenderedImage; import org.hedgecode.chess.position.Position; /** - * + * Storage class for chess diagrams. * * @author Dmitry Samoshin aka gotty */ diff --git a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/DiagramBuilder.java b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/DiagramBuilder.java index 10b4792..341b452 100644 --- a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/DiagramBuilder.java +++ b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/DiagramBuilder.java @@ -35,7 +35,7 @@ import org.hedgecode.chess.position.Positions; import org.hedgecode.chess.position.Square; /** - * + * Builder for chess diagrams. * * @author Dmitry Samoshin aka gotty */ @@ -66,7 +66,7 @@ public class DiagramBuilder implements ImageBuilder { int squareSize = board.squareSize(); - BufferedImage image = board.render(); + BufferedImage image = board.getBoard(); Graphics imageGraphics = image.getGraphics(); for (int y = 0; y < Square.getSize(); ++y) { for (int x = 0; x < Square.getSize(); ++x) { @@ -76,7 +76,7 @@ public class DiagramBuilder implements ImageBuilder { imageGraphics.drawImage( pieces.get(colorPiece).getScaledInstance( squareSize, squareSize, Image.SCALE_SMOOTH - ), + ), // todo: scale in other place x * squareSize, y * squareSize, null @@ -98,7 +98,7 @@ public class DiagramBuilder implements ImageBuilder { ImageIO.write( DiagramBuilder.getInstance().build( - Positions.INITIAL.getPosition(), "test", "shade" + Positions.INITIAL.getPosition(), "test", "chess24" ).getImage(), ImageFormat.PNG.name(), new File("chessboard" + "." + ImageFormat.PNG.getExt()) diff --git a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/FilenameUtils.java b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/FilenameUtils.java index 4b6b773..f4f4719 100644 --- a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/FilenameUtils.java +++ b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/FilenameUtils.java @@ -36,6 +36,8 @@ public final class FilenameUtils { private static final String OS = System.getProperty("os.name").toLowerCase(); + private static final String WIN_OS_TEMPLATE = "win"; + public static String getName(final String fileName) { if (fileName == null) { return null; @@ -102,7 +104,7 @@ public final class FilenameUtils { } private static boolean isWindows() { - return (OS.contains("win")); + return (OS.contains(WIN_OS_TEMPLATE)); } private FilenameUtils() { diff --git a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageBuilder.java b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageBuilder.java index 68a8caa..304e923 100644 --- a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageBuilder.java +++ b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageBuilder.java @@ -19,7 +19,7 @@ package org.hedgecode.chess.img; import org.hedgecode.chess.position.Position; /** - * + * Common image builder interface. * * @author Dmitry Samoshin aka gotty */ diff --git a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageConstants.java b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageConstants.java index 6faac03..d197d47 100644 --- a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageConstants.java +++ b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageConstants.java @@ -31,6 +31,7 @@ public final class ImageConstants { public static final String DARK_SQUARE_FILENAME = "dark"; public static final String LIGHT_SQUARE_FILENAME = "light"; + public static final String BOARD_FILENAME = "board"; public static final String LOCALE_BUNDLE_FILE = "org.hedgecode.chess.img.LocalStrings"; diff --git a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageException.java b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageException.java index ec77467..2a177ae 100644 --- a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageException.java +++ b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageException.java @@ -31,12 +31,12 @@ public class ImageException extends Exception { private String localeKey; private String message; - ImageException(String localeKey) { + public ImageException(String localeKey) { this.localeKey = localeKey; this.message = null; } - ImageException(String localeKey, String message) { + public ImageException(String localeKey, String message) { this.localeKey = localeKey; this.message = message; } diff --git a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageFilter.java b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageFilter.java index a39255b..37a2e0e 100644 --- a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageFilter.java +++ b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageFilter.java @@ -22,9 +22,10 @@ import java.nio.file.Files; import java.nio.file.Path; /** - * + * Filter for images by name and extention. * * @author Dmitry Samoshin aka gotty + * @see DirectoryStream.Filter */ public class ImageFilter implements DirectoryStream.Filter { diff --git a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageFormat.java b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageFormat.java index 95380ba..238a7b4 100644 --- a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageFormat.java +++ b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageFormat.java @@ -23,41 +23,54 @@ import java.util.List; import javax.imageio.ImageIO; /** - * Supported image formats for reading/writing. + * Supported image formats for reading/writing, indicated by type. * * @author Dmitry Samoshin aka gotty */ public enum ImageFormat { - PNG ( new String[]{"png"} ), - GIF ( new String[]{"gif"} ), - JPG ( new String[]{"jpg", "jpeg"} ), - SVG ( new String[]{"svg"} ), // todo - BMP ( new String[]{"bmp", "wbmp"} ); + PNG ( Type.BITMAP, new String[]{"png"} ), + GIF ( Type.BITMAP, new String[]{"gif"} ), + JPG ( Type.BITMAP, new String[]{"jpg", "jpeg"} ), + BMP ( Type.BITMAP, new String[]{"bmp", "wbmp"} ), + SVG ( Type.VECTOR, new String[]{"svg"} ); - private String[] fortmatExts; + enum Type { + + BITMAP, + VECTOR + + } + + private Type formatType; + private String[] formatExts; private boolean isRead; private boolean isWrite; private static String[] allAvailableExts; - ImageFormat(String[] exts) { - fortmatExts = exts; + ImageFormat(Type type, String[] exts) { + formatType = type; + formatExts = exts; isRead = isExist( - ImageIO.getReaderFormatNames(), fortmatExts + ImageIO.getReaderFormatNames(), formatExts ); isWrite = isExist( - ImageIO.getWriterFormatNames(), fortmatExts + ImageIO.getWriterFormatNames(), formatExts ); } + public Type getType() { + return formatType; + } + public String getExt() { - return fortmatExts[0]; + return formatExts[0]; } public String[] getExts() { - return fortmatExts; + return formatExts; } public boolean isRead() { @@ -99,15 +112,4 @@ public enum ImageFormat { return false; } - -/* - public static void main(String[] args) { - ImageFormat imageFormat = JPG; - System.out.println("Supported format: " + imageFormat); - imageFormat = findFormat("jpeg"); - imageFormat = findFormat("svg"); - imageFormat = findFormat("jpeeg"); - } -*/ - } \ No newline at end of file diff --git a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageFormatShaper.java b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageFormatShaper.java new file mode 100644 index 0000000..5c1aea2 --- /dev/null +++ b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageFormatShaper.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018-2019. Developed by Hedgecode. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.hedgecode.chess.img; + +import java.awt.image.BufferedImage; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +import org.hedgecode.chess.img.bitmap.BitmapImageShaper; +import org.hedgecode.chess.img.vector.VectorImageShaper; + +import static org.hedgecode.chess.img.ImageFormat.Type; + +/** + * Shaper for images, indicated by type format. + * + * @author Dmitry Samoshin aka gotty + */ +public final class ImageFormatShaper { + + private static ImageFormatShaper _instance = new ImageFormatShaper(); + + private Map imageShapers = new HashMap<>(); + + private ImageFormatShaper() { + imageShapers.put( + Type.BITMAP, + BitmapImageShaper.create() + ); + imageShapers.put( + Type.VECTOR, + VectorImageShaper.create() + ); + } + + public BufferedImage shape(String imageFormat, InputStream imageStream, int size) + throws ImageException + { + ImageFormat format = ImageFormat.findFormat(imageFormat); + if (format != null) { + ImageShaper imageShaper = imageShapers.get( + format.getType() + ); + return imageShaper.shape(imageStream, size); + } else { + throw new ImageException("image.unknown.image.format", imageFormat); + } + } + + public static ImageFormatShaper getInstance() { + return _instance; + } + +} diff --git a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageLoader.java b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageLoader.java index 1eee4c2..9267a05 100644 --- a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageLoader.java +++ b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageLoader.java @@ -17,7 +17,7 @@ package org.hedgecode.chess.img; /** - * + * Common image loader interface. * * @author Dmitry Samoshin aka gotty */ diff --git a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageShaper.java b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageShaper.java new file mode 100644 index 0000000..36f3e40 --- /dev/null +++ b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageShaper.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018-2019. Developed by Hedgecode. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.hedgecode.chess.img; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.InputStream; +import java.net.URL; + +/** + * Common image shaper interface. + * + * @author Dmitry Samoshin aka gotty + */ +public interface ImageShaper { + + BufferedImage shape(InputStream imageStream, int size) throws ImageException; + + BufferedImage shape(URL imageUrl, int size) throws ImageException; + + BufferedImage shape(File imageFile, int size) throws ImageException; + +} diff --git a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/bitmap/BitmapImageShaper.java b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/bitmap/BitmapImageShaper.java new file mode 100644 index 0000000..10a8e33 --- /dev/null +++ b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/bitmap/BitmapImageShaper.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2018-2019. Developed by Hedgecode. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.hedgecode.chess.img.bitmap; + +import java.awt.Graphics; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +import javax.imageio.ImageIO; + +import org.hedgecode.chess.img.ImageException; +import org.hedgecode.chess.img.ImageShaper; + +/** + * Shaper for bitmap images. + * + * @author Dmitry Samoshin aka gotty + */ +public class BitmapImageShaper implements ImageShaper { + + private BitmapImageShaper() { + } + + @Override + public BufferedImage shape(InputStream imageStream, int size) throws ImageException { + try { + return scaledImage( + ImageIO.read(imageStream), + size + ); + } catch (IOException e) { + throw new ImageException("image.unable.load.bitmap", e.getMessage()); + } + } + + @Override + public BufferedImage shape(URL imageUrl, int size) throws ImageException { + try { + return scaledImage( + ImageIO.read(imageUrl), + size + ); + } catch (IOException e) { + throw new ImageException("image.unable.load.bitmap", e.getMessage()); + } + } + + @Override + public BufferedImage shape(File imageFile, int size) throws ImageException { + try { + return scaledImage( + ImageIO.read(imageFile), + size + ); + } catch (IOException e) { + throw new ImageException("image.unable.load.bitmap", e.getMessage()); + } + } + + private BufferedImage scaledImage(BufferedImage image, int size) { + if (image.getWidth() == size && image.getHeight() == size) { + return image; + } + BufferedImage scaledImage = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB); + Graphics graphics = scaledImage.createGraphics(); + graphics.drawImage( + image.getScaledInstance(size, size, BufferedImage.SCALE_SMOOTH), + 0, 0, null + ); + graphics.dispose(); + return scaledImage; + } + + public static ImageShaper create() { + return new BitmapImageShaper(); + } + +} diff --git a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/board/Board.java b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/board/Board.java index f251e13..ab4371f 100644 --- a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/board/Board.java +++ b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/board/Board.java @@ -22,22 +22,29 @@ import java.awt.image.BufferedImage; import org.hedgecode.chess.position.Square; /** - * + * Storage class for chess board images. * * @author Dmitry Samoshin aka gotty */ public class Board { + private BufferedImage board; private SquarePair squares; + private int squareSize; - Board(SquarePair squares) { + private Board(SquarePair squares) { this.squares = squares; int width = Math.max(squares.getDark().getWidth(), squares.getLight().getWidth()); int height = Math.max(squares.getDark().getHeight(), squares.getLight().getHeight()); this.squareSize = Math.max(width, height); } + private Board(BufferedImage board) { + this.board = board; + this.squareSize = Math.max(board.getWidth(), board.getHeight()) / Square.getSize(); + } + public int squareSize() { return squareSize; } @@ -46,7 +53,14 @@ public class Board { return squareSize * Square.getSize(); } - public BufferedImage render() { + public BufferedImage getBoard() { + if (board == null && squares != null) { + board = renderBoard(); + } + return board; + } + + private BufferedImage renderBoard() { BufferedImage board = new BufferedImage( squareSize * Square.getSize(), squareSize * Square.getSize(), @@ -68,6 +82,10 @@ public class Board { return board; } + public static Board create(BufferedImage board) { + return new Board(board); + } + public static Board create(SquarePair squares) { return new Board(squares); } diff --git a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/board/BoardLoader.java b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/board/BoardLoader.java index c61bd98..e171418 100644 --- a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/board/BoardLoader.java +++ b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/board/BoardLoader.java @@ -27,7 +27,7 @@ import org.hedgecode.chess.img.ImageException; import org.hedgecode.chess.img.ImageFilter; /** - * + * Loader for chess board's set of images. * * @author Dmitry Samoshin aka gotty */ @@ -38,21 +38,20 @@ public class BoardLoader extends AbstractImageLoader { private static final String SQUARE_DARK = ImageConstants.DARK_SQUARE_FILENAME; private static final String SQUARE_LIGHT = ImageConstants.LIGHT_SQUARE_FILENAME; - private static final String[] SQUARE_NAMES = {SQUARE_DARK, SQUARE_LIGHT}; + private static final String BOARD = ImageConstants.BOARD_FILENAME; + + private static final String[] BOARD_SQUARE_NAMES = { BOARD, SQUARE_DARK, SQUARE_LIGHT }; private Map squareSetMap = new HashMap<>(); @Override public Board load(String name) throws ImageException { - Board board = null; + Board board; if (Type.STATELESS.equals(loadType()) || !squareSetMap.containsKey(name)) { String boardPath = FilenameUtils.getFullPath(SQUARES_DIR, name); - SquarePair squarePair = loadSquares(boardPath); - if (squarePair != null) { - board = Board.create(squarePair); - if (Type.STATEFUL.equals(loadType())) { - squareSetMap.put(name, board); - } + board = loadBoard(boardPath); + if (Type.STATEFUL.equals(loadType())) { + squareSetMap.put(name, board); } } else { board = squareSetMap.get(name); @@ -72,17 +71,22 @@ public class BoardLoader extends AbstractImageLoader { squareSetMap.clear(); } - private SquarePair loadSquares(String boardPath) throws ImageException { + private Board loadBoard(String boardPath) throws ImageException { Map images = loadImages( boardPath, - new ImageFilter(SQUARE_NAMES) + new ImageFilter(BOARD_SQUARE_NAMES) ); - BufferedImage dark = images.get(SQUARE_DARK); - BufferedImage light = images.get(SQUARE_LIGHT); - return (dark != null && light != null) - ? SquarePair.create(dark, light) - : null; // todo: ImageException + BufferedImage board = images.get(BOARD); + SquarePair squarePair = SquarePair.create( + images.get(SQUARE_DARK), images.get(SQUARE_LIGHT) + ); + if (board == null && !squarePair.isFilled()) { + throw new ImageException("image.incomplete.board.set", boardPath); + } + return board != null + ? Board.create(board) + : Board.create(squarePair); } } diff --git a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/board/SquarePair.java b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/board/SquarePair.java index 836d273..5fcdd66 100644 --- a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/board/SquarePair.java +++ b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/board/SquarePair.java @@ -20,7 +20,7 @@ import java.awt.image.BufferedImage; import java.util.Objects; /** - * + * Storage class for set of images of chess board squares. * * @author Dmitry Samoshin aka gotty */ @@ -29,7 +29,7 @@ public class SquarePair { private final T dark; private final T light; - SquarePair(T dark, T light) { + private SquarePair(T dark, T light) { this.dark = dark; this.light = light; } @@ -42,6 +42,13 @@ public class SquarePair { return light; } + public boolean isFilled() { + if (this.dark == null || this.light == null) { + return false; + } + return true; + } + @Override public boolean equals(Object o) { if (!(o instanceof SquarePair)) { diff --git a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/fs/DefFileSystemContractor.java b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/fs/DefFileSystemContractor.java index 58e85ee..ef9fd93 100644 --- a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/fs/DefFileSystemContractor.java +++ b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/fs/DefFileSystemContractor.java @@ -27,7 +27,7 @@ import java.nio.file.Path; import org.hedgecode.chess.img.FilenameUtils; /** - * + * Default FileSystem contractor. * * @author Dmitry Samoshin aka gotty */ diff --git a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/fs/FileSystemContractor.java b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/fs/FileSystemContractor.java index 1ca4831..32f4244 100644 --- a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/fs/FileSystemContractor.java +++ b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/fs/FileSystemContractor.java @@ -22,9 +22,10 @@ import java.nio.file.FileSystem; import java.nio.file.Path; /** - * + * Common FileSystem contractor interface. * * @author Dmitry Samoshin aka gotty + * @see FileSystem */ public interface FileSystemContractor extends AutoCloseable { diff --git a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/fs/FileSystemDetector.java b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/fs/FileSystemDetector.java index 2534c4f..66cd6e5 100644 --- a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/fs/FileSystemDetector.java +++ b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/fs/FileSystemDetector.java @@ -20,7 +20,7 @@ import java.io.IOException; import java.net.URI; /** - * File System Detector. + * FileSystem Detector. * * @author Dmitry Samoshin aka gotty */ diff --git a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/fs/JarFileSystemContractor.java b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/fs/JarFileSystemContractor.java index a3d403c..a57dfbb 100644 --- a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/fs/JarFileSystemContractor.java +++ b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/fs/JarFileSystemContractor.java @@ -27,7 +27,7 @@ import java.util.Collections; import org.hedgecode.chess.img.FilenameUtils; /** - * + * FileSystem contractor for jar-files. * * @author Dmitry Samoshin aka gotty */ diff --git a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/piece/PieceSet.java b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/piece/PieceSet.java index 342ba1a..58faf41 100644 --- a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/piece/PieceSet.java +++ b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/piece/PieceSet.java @@ -27,7 +27,7 @@ import org.hedgecode.chess.position.ColorPiece; import org.hedgecode.chess.position.Piece; /** - * + * Storage class for set of images of chess pieces. * * @author Dmitry Samoshin aka gotty */ @@ -37,7 +37,7 @@ public class PieceSet { private static String[] allPieceNames; - PieceSet() { + private PieceSet() { } public void add(String name, BufferedImage image) { @@ -65,7 +65,7 @@ public class PieceSet { return pieceSetMap.get(colorPiece); } - public boolean isFull() { + public boolean isFilled() { for (ColorPiece colorPiece : ColorPiece.values()) { if (!pieceSetMap.containsKey(colorPiece) || (pieceSetMap.get(colorPiece) == null)) { diff --git a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/piece/PieceSetLoader.java b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/piece/PieceSetLoader.java index 4cd68c0..8b0e7c8 100644 --- a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/piece/PieceSetLoader.java +++ b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/piece/PieceSetLoader.java @@ -27,7 +27,7 @@ import org.hedgecode.chess.img.ImageException; import org.hedgecode.chess.img.ImageFilter; /** - * + * Loader for chess piece's set of images. * * @author Dmitry Samoshin aka gotty */ @@ -45,7 +45,7 @@ public class PieceSetLoader extends AbstractImageLoader { if (Type.STATELESS.equals(loadType()) || !pieceSetMap.containsKey(name)) { String piecePath = FilenameUtils.getFullPath(PIECES_DIR, name); pieceSet = loadPieces(piecePath); - if (Type.STATEFUL.equals(loadType()) && pieceSet != null) { + if (Type.STATEFUL.equals(loadType())) { pieceSetMap.put(name, pieceSet); } } else { @@ -79,9 +79,10 @@ public class PieceSetLoader extends AbstractImageLoader { images.get(name) ); } - return pieceSet.isFull() - ? pieceSet - : null; // todo: ImageException + if (!pieceSet.isFilled()) { + throw new ImageException("image.incomplete.piece.set", piecePath); + } + return pieceSet; } } diff --git a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/vector/SquareImageTranscoder.java b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/vector/SquareImageTranscoder.java new file mode 100644 index 0000000..deeb890 --- /dev/null +++ b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/vector/SquareImageTranscoder.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2018-2019. Developed by Hedgecode. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.hedgecode.chess.img.vector; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +import javax.imageio.ImageIO; + +import org.apache.batik.transcoder.TranscoderException; +import org.apache.batik.transcoder.TranscoderInput; +import org.apache.batik.transcoder.TranscoderOutput; +import org.apache.batik.transcoder.image.ImageTranscoder; + +import org.hedgecode.chess.img.ImageFormat; + +/** + * Transcoder for vector square images to {@link BufferedImage}. + * + * @author Dmitry Samoshin aka gotty + * @see ImageTranscoder + */ +public class SquareImageTranscoder extends ImageTranscoder { + + private final int type; + private BufferedImage image; + + SquareImageTranscoder(int type) { + this.type = type; + } + + SquareImageTranscoder(int type, int size) { + this.type = type; + addTranscodingHint(ImageTranscoder.KEY_WIDTH, (float) size); + addTranscodingHint(ImageTranscoder.KEY_HEIGHT, (float) size); + + } + + @Override + protected void setImageSize(float width, float height) { + if (width > 0 && height > 0) { + super.setImageSize(width, height); + } + } + + @Override + public BufferedImage createImage(int width, int height) { + return new BufferedImage(width, height, type); + } + + @Override + public void writeImage(BufferedImage image, TranscoderOutput to) throws TranscoderException { + this.image = image; + } + + public BufferedImage transcode(InputStream inputStream) throws TranscoderException { + transcode( + new TranscoderInput(inputStream), + null + ); + return getImage(); + } + + public BufferedImage getImage() { + return image; + } + + + public static void main(String[] args) throws TranscoderException, IOException { + SquareImageTranscoder imageTranscoder = + new SquareImageTranscoder(BufferedImage.TYPE_INT_ARGB); // , 250 + ImageIO.write( + imageTranscoder.transcode( + ClassLoader.getSystemResourceAsStream("images/pieces/spatial/bb.svg") + ), + ImageFormat.PNG.name(), + new File("bishop" + "." + ImageFormat.PNG.getExt()) + ); + } + +} diff --git a/chesshog-graphics/src/main/java/org/hedgecode/chess/img/vector/VectorImageShaper.java b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/vector/VectorImageShaper.java new file mode 100644 index 0000000..bd11dcf --- /dev/null +++ b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/vector/VectorImageShaper.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2018-2019. Developed by Hedgecode. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.hedgecode.chess.img.vector; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +import org.apache.batik.transcoder.TranscoderException; + +import org.hedgecode.chess.img.ImageException; +import org.hedgecode.chess.img.ImageShaper; + +/** + * Shaper for vector images. + * + * @author Dmitry Samoshin aka gotty + */ +public class VectorImageShaper implements ImageShaper { + + private VectorImageShaper() { + } + + @Override + public BufferedImage shape(InputStream imageStream, int size) throws ImageException { + SquareImageTranscoder imageTranscoder = + new SquareImageTranscoder(BufferedImage.TYPE_INT_ARGB, size); + try { + return imageTranscoder.transcode(imageStream); + } catch (TranscoderException e) { + throw new ImageException("image.unable.load.vector", e.getMessage()); + } + } + + @Override + public BufferedImage shape(URL imageUrl, int size) throws ImageException { + try { + return shape( + imageUrl.openStream(), + size + ); + } catch (IOException e) { + throw new ImageException("image.unable.load.vector", e.getMessage()); + } + } + + @Override + public BufferedImage shape(File imageFile, int size) throws ImageException { + try { + return shape( + new FileInputStream(imageFile), + size + ); + } catch (FileNotFoundException e) { + throw new ImageException("image.unable.load.vector", e.getMessage()); + } + } + + public static ImageShaper create() { + return new VectorImageShaper(); + } + +} diff --git a/chesshog-graphics/src/main/resources/org/hedgecode/chess/img/LocalStrings.properties b/chesshog-graphics/src/main/resources/org/hedgecode/chess/img/LocalStrings.properties index b97b5ef..75bd45e 100644 --- a/chesshog-graphics/src/main/resources/org/hedgecode/chess/img/LocalStrings.properties +++ b/chesshog-graphics/src/main/resources/org/hedgecode/chess/img/LocalStrings.properties @@ -17,3 +17,8 @@ image.unable.access.resource=Unable to access resources of graphic module image.unable.find.resource=Unable to find image resources +image.unable.load.bitmap=Unable to load bitmap image +image.unable.load.vector=Unable to load vector image +image.unknown.image.format=Unknown image format +image.incomplete.board.set=Incomplete board set for load +image.incomplete.piece.set=Incomplete piece set for load diff --git a/chesshog-graphics/src/main/resources/org/hedgecode/chess/img/LocalStrings_ru.properties b/chesshog-graphics/src/main/resources/org/hedgecode/chess/img/LocalStrings_ru.properties index 8e821e6..8def590 100644 --- a/chesshog-graphics/src/main/resources/org/hedgecode/chess/img/LocalStrings_ru.properties +++ b/chesshog-graphics/src/main/resources/org/hedgecode/chess/img/LocalStrings_ru.properties @@ -16,3 +16,8 @@ image.unable.access.resource=\u041D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u0434\u043E\u0441\u0442\u0443\u043F \u043A \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043C \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043A\u043E\u0433\u043E \u043C\u043E\u0434\u0443\u043B\u044F image.unable.find.resource=\u041D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E \u043D\u0430\u0439\u0442\u0438 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043A\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044B +image.unable.load.bitmap=\u041D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0440\u0430\u0441\u0442\u0440\u043E\u0432\u043E\u0435 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 +image.unable.load.vector=\u041D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0432\u0435\u043A\u0442\u043E\u0440\u043D\u043E\u0435 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 +image.unknown.image.format=\u041D\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043D\u044B\u0439 \u0444\u043E\u0440\u043C\u0430\u0442 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F +image.incomplete.board.set=\u041D\u0435\u043F\u043E\u043B\u043D\u044B\u0439 \u043D\u0430\u0431\u043E\u0440 \u0434\u043B\u044F \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0438 \u0448\u0430\u0445\u043C\u0430\u0442\u043D\u043E\u0439 \u0434\u043E\u0441\u043A\u0438 +image.incomplete.piece.set=\u041D\u0435\u043F\u043E\u043B\u043D\u044B\u0439 \u043D\u0430\u0431\u043E\u0440 \u0434\u043B\u044F \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0438 \u0448\u0430\u0445\u043C\u0430\u0442\u043D\u044B\u0445 \u0444\u0438\u0433\u0443\u0440 -- 2.10.0