mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2026-05-28 00:00:03 -04:00
TMI-60: Support for clip paths in formats containing PSD resources
This commit is contained in:
+134
@@ -0,0 +1,134 @@
|
||||
package com.twelvemonkeys.imageio.path;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import static com.twelvemonkeys.imageio.path.PathsTest.assertPathEquals;
|
||||
import static com.twelvemonkeys.imageio.path.PathsTest.readExpectedPath;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
public class AdobePathBuilderTest {
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCreateNullBytes() {
|
||||
new AdobePathBuilder((byte[]) null);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCreateNull() {
|
||||
new AdobePathBuilder((DataInput) null);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCreateEmpty() {
|
||||
new AdobePathBuilder(new byte[0]);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCreateShortPath() {
|
||||
new AdobePathBuilder(new byte[3]);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCreateImpossiblePath() {
|
||||
new AdobePathBuilder(new byte[7]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreate() {
|
||||
new AdobePathBuilder(new byte[52]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoPath() throws IOException {
|
||||
Path2D path = new AdobePathBuilder(new byte[26]).path();
|
||||
assertNotNull(path);
|
||||
}
|
||||
|
||||
@Test(expected = IIOException.class)
|
||||
public void testShortPath() throws IOException {
|
||||
byte[] data = new byte[26];
|
||||
ByteBuffer buffer = ByteBuffer.wrap(data);
|
||||
buffer.putShort((short) AdobePathSegment.CLOSED_SUBPATH_LENGTH_RECORD);
|
||||
buffer.putShort((short) 1);
|
||||
|
||||
Path2D path = new AdobePathBuilder(data).path();
|
||||
assertNotNull(path);
|
||||
}
|
||||
|
||||
@Test(expected = IIOException.class)
|
||||
public void testShortPathToo() throws IOException {
|
||||
byte[] data = new byte[52];
|
||||
ByteBuffer buffer = ByteBuffer.wrap(data);
|
||||
buffer.putShort((short) AdobePathSegment.CLOSED_SUBPATH_LENGTH_RECORD);
|
||||
buffer.putShort((short) 2);
|
||||
buffer.position(buffer.position() + 22);
|
||||
buffer.putShort((short) AdobePathSegment.CLOSED_SUBPATH_BEZIER_LINKED);
|
||||
|
||||
Path2D path = new AdobePathBuilder(data).path();
|
||||
assertNotNull(path);
|
||||
}
|
||||
|
||||
@Test(expected = IIOException.class)
|
||||
public void testLongPath() throws IOException {
|
||||
byte[] data = new byte[78];
|
||||
ByteBuffer buffer = ByteBuffer.wrap(data);
|
||||
buffer.putShort((short) AdobePathSegment.CLOSED_SUBPATH_LENGTH_RECORD);
|
||||
buffer.putShort((short) 1);
|
||||
buffer.position(buffer.position() + 22);
|
||||
buffer.putShort((short) AdobePathSegment.CLOSED_SUBPATH_BEZIER_LINKED);
|
||||
buffer.position(buffer.position() + 24);
|
||||
buffer.putShort((short) AdobePathSegment.CLOSED_SUBPATH_BEZIER_LINKED);
|
||||
|
||||
Path2D path = new AdobePathBuilder(data).path();
|
||||
assertNotNull(path);
|
||||
}
|
||||
|
||||
@Test(expected = IIOException.class)
|
||||
public void testPathMissingLength() throws IOException {
|
||||
byte[] data = new byte[26];
|
||||
ByteBuffer buffer = ByteBuffer.wrap(data);
|
||||
buffer.putShort((short) AdobePathSegment.CLOSED_SUBPATH_BEZIER_LINKED);
|
||||
|
||||
Path2D path = new AdobePathBuilder(data).path();
|
||||
assertNotNull(path);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimplePath() throws IOException {
|
||||
// We'll read this from a real file, with hardcoded offsets for simplicity
|
||||
// PSD IRB: offset: 34, length: 32598
|
||||
// Clipping path: offset: 31146, length: 1248
|
||||
ImageInputStream stream = PathsTest.resourceAsIIOStream("/psd/grape_with_path.psd");
|
||||
stream.seek(34 + 31146);
|
||||
byte[] data = new byte[1248];
|
||||
stream.readFully(data);
|
||||
|
||||
Path2D path = new AdobePathBuilder(data).path();
|
||||
|
||||
assertNotNull(path);
|
||||
assertPathEquals(path, readExpectedPath("/ser/grape-path.ser"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testComplexPath() throws IOException {
|
||||
// We'll read this from a real file, with hardcoded offsets for simplicity
|
||||
// PSD IRB: offset: 16970, length: 11152
|
||||
// Clipping path: offset: 9250, length: 1534
|
||||
ImageInputStream stream = PathsTest.resourceAsIIOStream("/tiff/big-endian-multiple-clips.tif");
|
||||
stream.seek(16970 + 9250);
|
||||
byte[] data = new byte[1534];
|
||||
stream.readFully(data);
|
||||
|
||||
Path2D path = new AdobePathBuilder(data).path();
|
||||
|
||||
assertNotNull(path);
|
||||
assertPathEquals(path, readExpectedPath("/ser/multiple-clips.ser"));
|
||||
}
|
||||
}
|
||||
+229
@@ -0,0 +1,229 @@
|
||||
package com.twelvemonkeys.imageio.path;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* AdobePathSegmentTest.
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: harald.kuhr$
|
||||
* @version $Id: AdobePathSegmentTest.java,v 1.0 13/12/14 harald.kuhr Exp$
|
||||
*/
|
||||
public class AdobePathSegmentTest {
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCreateBadSelectorNegative() {
|
||||
new AdobePathSegment(-1, 1);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCreateBadSelector() {
|
||||
new AdobePathSegment(9, 2);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCreateOpenLengthRecordNegative() {
|
||||
new AdobePathSegment(AdobePathSegment.OPEN_SUBPATH_LENGTH_RECORD, -1);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateOpenLengthRecord() {
|
||||
AdobePathSegment segment = new AdobePathSegment(AdobePathSegment.OPEN_SUBPATH_LENGTH_RECORD, 42);
|
||||
|
||||
assertEquals(AdobePathSegment.OPEN_SUBPATH_LENGTH_RECORD, segment.selector);
|
||||
assertEquals(42, segment.length);
|
||||
assertEquals(-1, segment.cppx, 0);
|
||||
assertEquals(-1, segment.cppy, 0);
|
||||
assertEquals(-1, segment.apx, 0);
|
||||
assertEquals(-1, segment.apy, 0);
|
||||
assertEquals(-1, segment.cplx, 0);
|
||||
assertEquals(-1, segment.cply, 0);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCreateClosedLengthRecordNegative() {
|
||||
new AdobePathSegment(AdobePathSegment.CLOSED_SUBPATH_LENGTH_RECORD, -42);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateClosedLengthRecord() {
|
||||
AdobePathSegment segment = new AdobePathSegment(AdobePathSegment.CLOSED_SUBPATH_LENGTH_RECORD, 27);
|
||||
|
||||
assertEquals(AdobePathSegment.CLOSED_SUBPATH_LENGTH_RECORD, segment.selector);
|
||||
assertEquals(27, segment.length);
|
||||
assertEquals(-1, segment.cppx, 0);
|
||||
assertEquals(-1, segment.cppy, 0);
|
||||
assertEquals(-1, segment.apx, 0);
|
||||
assertEquals(-1, segment.apy, 0);
|
||||
assertEquals(-1, segment.cplx, 0);
|
||||
assertEquals(-1, segment.cply, 0);
|
||||
}
|
||||
|
||||
/// Open subpath
|
||||
|
||||
@Test
|
||||
public void testCreateOpenLinkedRecord() {
|
||||
AdobePathSegment segment = new AdobePathSegment(AdobePathSegment.OPEN_SUBPATH_BEZIER_LINKED, .5, .5, 0, 0, 1, 1);
|
||||
|
||||
assertEquals(AdobePathSegment.OPEN_SUBPATH_BEZIER_LINKED, segment.selector);
|
||||
assertEquals(-1, segment.length);
|
||||
assertEquals(.5, segment.cppx, 0);
|
||||
assertEquals(.5, segment.cppy, 0);
|
||||
assertEquals(0, segment.apx, 0);
|
||||
assertEquals(0, segment.apy, 0);
|
||||
assertEquals(1, segment.cplx, 0);
|
||||
assertEquals(1, segment.cply, 0);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCreateOpenLinkedRecordBad() {
|
||||
new AdobePathSegment(AdobePathSegment.OPEN_SUBPATH_BEZIER_LINKED, 44);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCreateOpenLinkedRecordNegative() {
|
||||
new AdobePathSegment(AdobePathSegment.OPEN_SUBPATH_BEZIER_LINKED, -.5, -.5, 0, 0, 1, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateOpenUnlinkedRecord() {
|
||||
AdobePathSegment segment = new AdobePathSegment(AdobePathSegment.OPEN_SUBPATH_BEZIER_UNLINKED, .5, .5, 0, 0, 1, 1);
|
||||
|
||||
assertEquals(AdobePathSegment.OPEN_SUBPATH_BEZIER_UNLINKED, segment.selector);
|
||||
assertEquals(-1, segment.length);
|
||||
assertEquals(.5, segment.cppx, 0);
|
||||
assertEquals(.5, segment.cppy, 0);
|
||||
assertEquals(0, segment.apx, 0);
|
||||
assertEquals(0, segment.apy, 0);
|
||||
assertEquals(1, segment.cplx, 0);
|
||||
assertEquals(1, segment.cply, 0);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCreateOpenUnlinkedRecordBad() {
|
||||
new AdobePathSegment(AdobePathSegment.OPEN_SUBPATH_BEZIER_UNLINKED, 44);
|
||||
}
|
||||
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCreateOpenUnlinkedRecordNegative() {
|
||||
new AdobePathSegment(AdobePathSegment.OPEN_SUBPATH_BEZIER_UNLINKED, -.5, -.5, 0, 0, 1, 1);
|
||||
}
|
||||
|
||||
/// Closed subpath
|
||||
|
||||
@Test
|
||||
public void testCreateClosedLinkedRecord() {
|
||||
AdobePathSegment segment = new AdobePathSegment(AdobePathSegment.CLOSED_SUBPATH_BEZIER_LINKED, .5, .5, 0, 0, 1, 1);
|
||||
|
||||
assertEquals(AdobePathSegment.CLOSED_SUBPATH_BEZIER_LINKED, segment.selector);
|
||||
assertEquals(-1, segment.length);
|
||||
assertEquals(.5, segment.cppx, 0);
|
||||
assertEquals(.5, segment.cppy, 0);
|
||||
assertEquals(0, segment.apx, 0);
|
||||
assertEquals(0, segment.apy, 0);
|
||||
assertEquals(1, segment.cplx, 0);
|
||||
assertEquals(1, segment.cply, 0);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCreateClosedLinkedRecordBad() {
|
||||
new AdobePathSegment(AdobePathSegment.CLOSED_SUBPATH_BEZIER_LINKED, 44);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCreateClosedLinkedRecordNegative() {
|
||||
new AdobePathSegment(AdobePathSegment.CLOSED_SUBPATH_BEZIER_LINKED, -.5, -.5, 0, 0, 1, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateClosedUnlinkedRecord() {
|
||||
AdobePathSegment segment = new AdobePathSegment(AdobePathSegment.CLOSED_SUBPATH_BEZIER_UNLINKED, .5, .5, 0, 0, 1, 1);
|
||||
|
||||
assertEquals(AdobePathSegment.CLOSED_SUBPATH_BEZIER_UNLINKED, segment.selector);
|
||||
assertEquals(-1, segment.length);
|
||||
assertEquals(.5, segment.cppx, 0);
|
||||
assertEquals(.5, segment.cppy, 0);
|
||||
assertEquals(0, segment.apx, 0);
|
||||
assertEquals(0, segment.apy, 0);
|
||||
assertEquals(1, segment.cplx, 0);
|
||||
assertEquals(1, segment.cply, 0);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCreateClosedUnlinkedRecordBad() {
|
||||
new AdobePathSegment(AdobePathSegment.CLOSED_SUBPATH_BEZIER_UNLINKED, 44);
|
||||
}
|
||||
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCreateClosedUnlinkedRecordNegative() {
|
||||
new AdobePathSegment(AdobePathSegment.CLOSED_SUBPATH_BEZIER_UNLINKED, -.5, -.5, 0, 0, 1, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToStringRule() {
|
||||
String string = new AdobePathSegment(AdobePathSegment.INITIAL_FILL_RULE_RECORD, 2).toString();
|
||||
assertTrue(string, string.startsWith("Rule"));
|
||||
assertTrue(string, string.contains("Initial"));
|
||||
assertTrue(string, string.contains("fill"));
|
||||
assertTrue(string, string.contains("rule=2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToStringLength() {
|
||||
String string = new AdobePathSegment(AdobePathSegment.CLOSED_SUBPATH_LENGTH_RECORD, 2).toString();
|
||||
assertTrue(string, string.startsWith("Len"));
|
||||
assertTrue(string, string.contains("Closed"));
|
||||
assertTrue(string, string.contains("subpath"));
|
||||
assertTrue(string, string.contains("totalPoints=2"));
|
||||
|
||||
string = new AdobePathSegment(AdobePathSegment.OPEN_SUBPATH_LENGTH_RECORD, 42).toString();
|
||||
assertTrue(string, string.startsWith("Len"));
|
||||
assertTrue(string, string.contains("Open"));
|
||||
assertTrue(string, string.contains("subpath"));
|
||||
assertTrue(string, string.contains("totalPoints=42"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToStringOther() {
|
||||
String string = new AdobePathSegment(AdobePathSegment.OPEN_SUBPATH_BEZIER_LINKED, 0, 0, 1, 1, 0, 0).toString();
|
||||
assertTrue(string, string.startsWith("Pt"));
|
||||
assertTrue(string, string.contains("Open"));
|
||||
assertTrue(string, string.contains("Bezier"));
|
||||
assertTrue(string, string.contains("linked"));
|
||||
|
||||
string = new AdobePathSegment(AdobePathSegment.CLOSED_SUBPATH_BEZIER_LINKED, 0, 0, 1, 1, 0, 0).toString();
|
||||
assertTrue(string, string.startsWith("Pt"));
|
||||
assertTrue(string, string.contains("Closed"));
|
||||
assertTrue(string, string.contains("Bezier"));
|
||||
assertTrue(string, string.contains("linked"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEqualsLength() {
|
||||
AdobePathSegment segment = new AdobePathSegment(AdobePathSegment.CLOSED_SUBPATH_LENGTH_RECORD, 2);
|
||||
assertEquals(new AdobePathSegment(AdobePathSegment.CLOSED_SUBPATH_LENGTH_RECORD, 2), segment);
|
||||
assertFalse(new AdobePathSegment(AdobePathSegment.CLOSED_SUBPATH_LENGTH_RECORD, 3).equals(segment));
|
||||
assertFalse(new AdobePathSegment(AdobePathSegment.OPEN_SUBPATH_LENGTH_RECORD, 2).equals(segment));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEqualsOther() {
|
||||
AdobePathSegment segment = new AdobePathSegment(AdobePathSegment.CLOSED_SUBPATH_BEZIER_LINKED, 0, 0, 1, 1, 0, 0);
|
||||
assertEquals(new AdobePathSegment(AdobePathSegment.CLOSED_SUBPATH_BEZIER_LINKED, 0, 0, 1, 1, 0, 0), segment);
|
||||
assertFalse(new AdobePathSegment(AdobePathSegment.OPEN_SUBPATH_BEZIER_LINKED, 0, 0, 1, 1, 0, 0).equals(segment));
|
||||
assertFalse(new AdobePathSegment(AdobePathSegment.CLOSED_SUBPATH_BEZIER_UNLINKED, 0, 0, 1, 1, 0, 0).equals(segment));
|
||||
assertFalse(new AdobePathSegment(AdobePathSegment.CLOSED_SUBPATH_BEZIER_LINKED, 0, 0.1, 1, 1, 0, 0).equals(segment));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHashCodeLength() {
|
||||
AdobePathSegment segment = new AdobePathSegment(AdobePathSegment.CLOSED_SUBPATH_LENGTH_RECORD, 2);
|
||||
assertEquals(new AdobePathSegment(AdobePathSegment.CLOSED_SUBPATH_LENGTH_RECORD, 2).hashCode(), segment.hashCode());
|
||||
assertFalse(new AdobePathSegment(AdobePathSegment.CLOSED_SUBPATH_LENGTH_RECORD, 3).hashCode() == segment.hashCode());
|
||||
assertFalse(new AdobePathSegment(AdobePathSegment.OPEN_SUBPATH_LENGTH_RECORD, 2).hashCode() == segment.hashCode());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
package com.twelvemonkeys.imageio.path;
|
||||
|
||||
import com.twelvemonkeys.imageio.stream.ByteArrayImageInputStream;
|
||||
import com.twelvemonkeys.imageio.stream.SubImageInputStream;
|
||||
import com.twelvemonkeys.imageio.stream.URLImageInputStreamSpi;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.spi.IIORegistry;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import java.awt.*;
|
||||
import java.awt.geom.GeneralPath;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.PathIterator;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* PathsTest.
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: harald.kuhr$
|
||||
* @version $Id: PathsTest.java,v 1.0 12/12/14 harald.kuhr Exp$
|
||||
*/
|
||||
public class PathsTest {
|
||||
static {
|
||||
IIORegistry.getDefaultInstance().registerServiceProvider(new URLImageInputStreamSpi());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testReadPathNull() throws IOException {
|
||||
Paths.readPath(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadPathUnknown() throws IOException {
|
||||
assertNull(Paths.readPath(new ByteArrayImageInputStream(new byte[42])));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrapeJPEG() throws IOException {
|
||||
ImageInputStream stream = resourceAsIIOStream("/jpeg/grape_with_path.jpg");
|
||||
|
||||
Path2D path = Paths.readPath(stream);
|
||||
|
||||
assertNotNull(path);
|
||||
assertPathEquals(readExpectedPath("/ser/grape-path.ser"), path);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrapePSD() throws IOException {
|
||||
ImageInputStream stream = resourceAsIIOStream("/psd/grape_with_path.psd");
|
||||
|
||||
Path2D path = Paths.readPath(stream);
|
||||
|
||||
assertNotNull(path);
|
||||
assertPathEquals(readExpectedPath("/ser/grape-path.ser"), path);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrapeTIFF() throws IOException {
|
||||
ImageInputStream stream = resourceAsIIOStream("/tiff/little-endian-grape_with_path.tif");
|
||||
|
||||
Path2D path = Paths.readPath(stream);
|
||||
|
||||
assertNotNull(path);
|
||||
assertPathEquals(readExpectedPath("/ser/grape-path.ser"), path);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleTIFF() throws IOException {
|
||||
ImageInputStream stream = resourceAsIIOStream("/tiff/big-endian-multiple-clips.tif");
|
||||
|
||||
Shape path = Paths.readPath(stream);
|
||||
|
||||
assertNotNull(path);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrape8BIM() throws IOException {
|
||||
ImageInputStream stream = resourceAsIIOStream("/psd/grape_with_path.psd");
|
||||
|
||||
// PSD image resources from position 34, length 32598
|
||||
stream.seek(34);
|
||||
stream = new SubImageInputStream(stream, 32598);
|
||||
|
||||
Path2D path = Paths.readPath(stream);
|
||||
|
||||
assertNotNull(path);
|
||||
assertPathEquals(readExpectedPath("/ser/grape-path.ser"), path);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testApplyClippingPathNullPath() throws IOException {
|
||||
Paths.applyClippingPath(null, new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_GRAY));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testApplyClippingPathNullSource() throws IOException {
|
||||
Paths.applyClippingPath(new GeneralPath(), null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplyClippingPath() throws IOException {
|
||||
BufferedImage source = new BufferedImage(20, 20, BufferedImage.TYPE_3BYTE_BGR);
|
||||
|
||||
Path2D path = readExpectedPath("/ser/grape-path.ser");
|
||||
|
||||
BufferedImage image = Paths.applyClippingPath(path, source);
|
||||
|
||||
assertNotNull(image);
|
||||
// Same dimensions as original
|
||||
assertEquals(source.getWidth(), image.getWidth());
|
||||
assertEquals(source.getHeight(), image.getHeight());
|
||||
// Transparent
|
||||
assertTrue(image.getColorModel().getTransparency() == Transparency.TRANSLUCENT);
|
||||
|
||||
// Corners (at least) should be transparent
|
||||
assertEquals(0, image.getRGB(0, 0));
|
||||
assertEquals(0, image.getRGB(source.getWidth() - 1, 0));
|
||||
assertEquals(0, image.getRGB(0, source.getHeight() - 1));
|
||||
assertEquals(0, image.getRGB(source.getWidth() - 1, source.getHeight() - 1));
|
||||
|
||||
// Center opaque
|
||||
assertEquals(0xff, image.getRGB(source.getWidth() / 2, source.getHeight() / 2) >>> 24);
|
||||
|
||||
// TODO: Mor sophisticated test that tests all pixels outside path...
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testApplyClippingPathNullDestination() throws IOException {
|
||||
Paths.applyClippingPath(new GeneralPath(), new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_GRAY), null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplyClippingPathCustomDestination() throws IOException {
|
||||
BufferedImage source = new BufferedImage(20, 20, BufferedImage.TYPE_3BYTE_BGR);
|
||||
|
||||
Path2D path = readExpectedPath("/ser/grape-path.ser");
|
||||
|
||||
// Destination is intentionally larger than source
|
||||
BufferedImage destination = new BufferedImage(30, 30, BufferedImage.TYPE_4BYTE_ABGR);
|
||||
BufferedImage image = Paths.applyClippingPath(path, source, destination);
|
||||
|
||||
assertSame(destination, image);
|
||||
|
||||
// Corners (at least) should be transparent
|
||||
assertEquals(0, image.getRGB(0, 0));
|
||||
assertEquals(0, image.getRGB(image.getWidth() - 1, 0));
|
||||
assertEquals(0, image.getRGB(0, image.getHeight() - 1));
|
||||
assertEquals(0, image.getRGB(image.getWidth() - 1, image.getHeight() - 1));
|
||||
|
||||
// "inner" corners
|
||||
assertEquals(0, image.getRGB(source.getWidth() - 1, 0));
|
||||
assertEquals(0, image.getRGB(0, source.getHeight() - 1));
|
||||
assertEquals(0, image.getRGB(source.getWidth() - 1, source.getHeight() - 1));
|
||||
|
||||
// Center opaque
|
||||
assertEquals(0xff, image.getRGB(source.getWidth() / 2, source.getHeight() / 2) >>> 24);
|
||||
|
||||
// TODO: Mor sophisticated test that tests all pixels outside path...
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testReadClippedNull() throws IOException {
|
||||
Paths.readClipped(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadClipped() throws IOException {
|
||||
BufferedImage image = Paths.readClipped(resourceAsIIOStream("/jpeg/grape_with_path.jpg"));
|
||||
|
||||
assertNotNull(image);
|
||||
// Same dimensions as original
|
||||
assertEquals(857, image.getWidth());
|
||||
assertEquals(1800, image.getHeight());
|
||||
// Transparent
|
||||
assertTrue(image.getColorModel().getTransparency() == Transparency.TRANSLUCENT);
|
||||
|
||||
// Corners (at least) should be transparent
|
||||
assertEquals(0, image.getRGB(0, 0));
|
||||
assertEquals(0, image.getRGB(image.getWidth() - 1, 0));
|
||||
assertEquals(0, image.getRGB(0, image.getHeight() - 1));
|
||||
assertEquals(0, image.getRGB(image.getWidth() - 1, image.getHeight() - 1));
|
||||
|
||||
// Center opaque
|
||||
assertEquals(0xff, image.getRGB(image.getWidth() / 2, image.getHeight() / 2) >>> 24);
|
||||
|
||||
// TODO: Mor sophisticated test that tests all pixels outside path...
|
||||
}
|
||||
|
||||
// TODO: Test read image without path, as no-op
|
||||
|
||||
static ImageInputStream resourceAsIIOStream(String name) throws IOException {
|
||||
return ImageIO.createImageInputStream(PathsTest.class.getResource(name));
|
||||
}
|
||||
|
||||
static Path2D readExpectedPath(final String resource) throws IOException {
|
||||
ObjectInputStream ois = new ObjectInputStream(PathsTest.class.getResourceAsStream(resource));
|
||||
|
||||
try {
|
||||
return (Path2D) ois.readObject();
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
finally {
|
||||
ois.close();
|
||||
}
|
||||
}
|
||||
|
||||
static void assertPathEquals(final Path2D expectedPath, final Path2D actualPath) {
|
||||
PathIterator expectedIterator = expectedPath.getPathIterator(null);
|
||||
PathIterator actualIterator = actualPath.getPathIterator(null);
|
||||
float[] expectedCoords = new float[6];
|
||||
float[] actualCoords = new float[6];
|
||||
|
||||
while(!actualIterator.isDone()) {
|
||||
int expectedType = expectedIterator.currentSegment(expectedCoords);
|
||||
int actualType = actualIterator.currentSegment(actualCoords);
|
||||
|
||||
assertEquals(expectedType, actualType);
|
||||
assertArrayEquals(expectedCoords, actualCoords, 0);
|
||||
|
||||
actualIterator.next();
|
||||
expectedIterator.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
Sample images kindly provided by itemMaster LLC (https://www.itemmaster.com/).
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 329 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 206 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user