[LIB-9] Add functional for transcoding vector images
authorgotty <gotty@hedgecode.org>
Sat, 27 Apr 2019 18:43:58 +0000 (21:43 +0300)
committergotty <gotty@hedgecode.org>
Sat, 27 Apr 2019 18:43:58 +0000 (21:43 +0300)
27 files changed:
chesshog-graphics/pom.xml
chesshog-graphics/src/main/java/org/hedgecode/chess/img/AbstractImageLoader.java
chesshog-graphics/src/main/java/org/hedgecode/chess/img/Diagram.java
chesshog-graphics/src/main/java/org/hedgecode/chess/img/DiagramBuilder.java
chesshog-graphics/src/main/java/org/hedgecode/chess/img/FilenameUtils.java
chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageBuilder.java
chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageConstants.java
chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageException.java
chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageFilter.java
chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageFormat.java
chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageFormatShaper.java [new file with mode: 0644]
chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageLoader.java
chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageShaper.java [new file with mode: 0644]
chesshog-graphics/src/main/java/org/hedgecode/chess/img/bitmap/BitmapImageShaper.java [new file with mode: 0644]
chesshog-graphics/src/main/java/org/hedgecode/chess/img/board/Board.java
chesshog-graphics/src/main/java/org/hedgecode/chess/img/board/BoardLoader.java
chesshog-graphics/src/main/java/org/hedgecode/chess/img/board/SquarePair.java
chesshog-graphics/src/main/java/org/hedgecode/chess/img/fs/DefFileSystemContractor.java
chesshog-graphics/src/main/java/org/hedgecode/chess/img/fs/FileSystemContractor.java
chesshog-graphics/src/main/java/org/hedgecode/chess/img/fs/FileSystemDetector.java
chesshog-graphics/src/main/java/org/hedgecode/chess/img/fs/JarFileSystemContractor.java
chesshog-graphics/src/main/java/org/hedgecode/chess/img/piece/PieceSet.java
chesshog-graphics/src/main/java/org/hedgecode/chess/img/piece/PieceSetLoader.java
chesshog-graphics/src/main/java/org/hedgecode/chess/img/vector/SquareImageTranscoder.java [new file with mode: 0644]
chesshog-graphics/src/main/java/org/hedgecode/chess/img/vector/VectorImageShaper.java [new file with mode: 0644]
chesshog-graphics/src/main/resources/org/hedgecode/chess/img/LocalStrings.properties
chesshog-graphics/src/main/resources/org/hedgecode/chess/img/LocalStrings_ru.properties

index 296bf2d..032e849 100644 (file)
         Hedgecode ChessHog Graphics Module.
     </description>
 
+    <properties>
+        <transcoderVersion>1.11</transcoderVersion>
+    </properties>
+
     <dependencies>
         <dependency>
             <groupId>org.hedgecode.chess</groupId>
             <artifactId>chesshog-format</artifactId>
             <version>${chessHogVersion}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.xmlgraphics</groupId>
+            <artifactId>batik-transcoder</artifactId>
+            <version>${transcoderVersion}</version>
+        </dependency>
     </dependencies>
 
 </project>
\ No newline at end of file
index c9c4f04..0d3681f 100644 (file)
@@ -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<String, BufferedImage> loadImages(String imagesPath, ImageFilter filter)
             throws ImageException
     {
+        return loadImages(imagesPath, filter, DEF_IMAGE_SIZE);
+    }
+
+    protected Map<String, BufferedImage> loadImages(String imagesPath, ImageFilter filter, int size)
+            throws ImageException
+    {
         Map<String, BufferedImage> images = new HashMap<>();
         try (FileSystemContractor fsc = FileSystemDetector.detect(getImageResourceUri())) {
             try (DirectoryStream<Path> 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
                             )
                     );
                 }
index 05b6381..6d62d86 100644 (file)
@@ -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
  */
index 10b4792..341b452 100644 (file)
@@ -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())
index 4b6b773..f4f4719 100644 (file)
@@ -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() {
index 68a8caa..304e923 100644 (file)
@@ -19,7 +19,7 @@ package org.hedgecode.chess.img;
 import org.hedgecode.chess.position.Position;
 
 /**
- *
+ * Common image builder interface.
  *
  * @author Dmitry Samoshin aka gotty
  */
index 6faac03..d197d47 100644 (file)
@@ -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";
 
index ec77467..2a177ae 100644 (file)
@@ -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;
     }
index a39255b..37a2e0e 100644 (file)
@@ -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<Path> {
 
index 95380ba..238a7b4 100644 (file)
@@ -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 (file)
index 0000000..5c1aea2
--- /dev/null
@@ -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<Type, ImageShaper> 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/ImageShaper.java b/chesshog-graphics/src/main/java/org/hedgecode/chess/img/ImageShaper.java
new file mode 100644 (file)
index 0000000..36f3e40
--- /dev/null
@@ -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 (file)
index 0000000..10a8e33
--- /dev/null
@@ -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();
+    }
+
+}
index f251e13..ab4371f 100644 (file)
@@ -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<BufferedImage> squares;
+
     private int squareSize;
 
-    Board(SquarePair<BufferedImage> squares) {
+    private Board(SquarePair<BufferedImage> 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<BufferedImage> squares) {
         return new Board(squares);
     }
index c61bd98..e171418 100644 (file)
@@ -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<String, Board> 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<BufferedImage> 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<BufferedImage> loadSquares(String boardPath) throws ImageException {
+    private Board loadBoard(String boardPath) throws ImageException {
         Map<String, BufferedImage> 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<BufferedImage> 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);
     }
 
 }
index 836d273..5fcdd66 100644 (file)
@@ -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<T> {
     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<T> {
         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)) {
index 1ca4831..32f4244 100644 (file)
@@ -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 {
 
index 2534c4f..66cd6e5 100644 (file)
@@ -20,7 +20,7 @@ import java.io.IOException;
 import java.net.URI;
 
 /**
- * File System Detector.
+ * FileSystem Detector.
  *
  * @author Dmitry Samoshin aka gotty
  */
index a3d403c..a57dfbb 100644 (file)
@@ -27,7 +27,7 @@ import java.util.Collections;
 import org.hedgecode.chess.img.FilenameUtils;
 
 /**
- *
+ * FileSystem contractor for jar-files.
  *
  * @author Dmitry Samoshin aka gotty
  */
index 342ba1a..58faf41 100644 (file)
@@ -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)) {
index 4cd68c0..8b0e7c8 100644 (file)
@@ -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 (file)
index 0000000..deeb890
--- /dev/null
@@ -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 (file)
index 0000000..bd11dcf
--- /dev/null
@@ -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();
+    }
+
+}
index b97b5ef..75bd45e 100644 (file)
@@ -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
index 8e821e6..8def590 100644 (file)
@@ -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