mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2026-04-04 00:00:01 -04:00
Core now moved to common.
This commit is contained in:
574
common/common-image/src/test/java/com/twelvemonkeys/image/ImageUtilTestCase.java
Executable file
574
common/common-image/src/test/java/com/twelvemonkeys/image/ImageUtilTestCase.java
Executable file
@@ -0,0 +1,574 @@
|
||||
|
||||
package com.twelvemonkeys.image;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
*
|
||||
* @author $author wmhakur$
|
||||
* @version $id: $
|
||||
* To change this template use Options | File Templates.
|
||||
*/
|
||||
public class ImageUtilTestCase extends TestCase {
|
||||
|
||||
private final static String IMAGE_NAME = "/sunflower.jpg";
|
||||
private BufferedImage mOriginal;
|
||||
private BufferedImage mImage;
|
||||
private Image mScaled;
|
||||
|
||||
public ImageUtilTestCase() throws Exception {
|
||||
mImage = new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB);
|
||||
mScaled = mImage.getScaledInstance(5, 5, Image.SCALE_FAST);
|
||||
|
||||
// Read image from class path
|
||||
InputStream is = getClass().getResourceAsStream(IMAGE_NAME);
|
||||
mOriginal = ImageIO.read(is);
|
||||
|
||||
assertNotNull(mOriginal);
|
||||
}
|
||||
|
||||
/*
|
||||
public void setUp() throws Exception {
|
||||
mImage = new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB);
|
||||
mScaled = mImage.getScaledInstance(5, 5, Image.SCALE_FAST);
|
||||
|
||||
// Read image from class path
|
||||
InputStream is = ClassLoader.getSystemResourceAsStream(IMAGE_NAME);
|
||||
mOriginal = ImageIO.read(is);
|
||||
|
||||
assertNotNull(mOriginal);
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
mOriginal = null;
|
||||
}
|
||||
*/
|
||||
|
||||
public void testToBufferedImageNull() {
|
||||
BufferedImage img = null;
|
||||
boolean threwRuntimeException = false;
|
||||
|
||||
try {
|
||||
img = ImageUtil.toBuffered((Image) null);
|
||||
}
|
||||
catch (RuntimeException ne) {
|
||||
threwRuntimeException = true;
|
||||
}
|
||||
// No input should return null
|
||||
assertNull(img);
|
||||
|
||||
// Should have thrown an exception
|
||||
assertTrue(threwRuntimeException);
|
||||
}
|
||||
|
||||
public void testToBufferedImageTypeNull() {
|
||||
BufferedImage img = null;
|
||||
boolean threwRuntimeException = false;
|
||||
|
||||
try {
|
||||
img = ImageUtil.toBuffered(null, BufferedImage.TYPE_INT_ARGB);
|
||||
}
|
||||
catch (RuntimeException ne) {
|
||||
threwRuntimeException = true;
|
||||
}
|
||||
// No input should return null
|
||||
assertNull(img);
|
||||
|
||||
// Should have thrown an exception
|
||||
assertTrue(threwRuntimeException);
|
||||
}
|
||||
|
||||
public void testImageIsNotBufferedImage() {
|
||||
// Should not be a buffered image
|
||||
assertFalse(
|
||||
"FOR SOME IMPLEMENTATIONS THIS MIGHT FAIL!\nIn that case, testToBufferedImage() will fail too.",
|
||||
mScaled instanceof BufferedImage
|
||||
);
|
||||
}
|
||||
|
||||
public void testToBufferedImage() {
|
||||
BufferedImage sameAsImage = ImageUtil.toBuffered((RenderedImage) mImage);
|
||||
BufferedImage bufferedScaled = ImageUtil.toBuffered(mScaled);
|
||||
|
||||
// Should be no need to convert
|
||||
assertSame(mImage, sameAsImage);
|
||||
|
||||
// Should have same dimensions
|
||||
assertEquals(mScaled.getWidth(null), bufferedScaled.getWidth());
|
||||
assertEquals(mScaled.getHeight(null), bufferedScaled.getHeight());
|
||||
|
||||
// Hmmm...
|
||||
assertTrue(new Integer(42).equals(bufferedScaled.getProperty("lucky-number"))
|
||||
|| bufferedScaled.getPropertyNames() == null
|
||||
|| bufferedScaled.getPropertyNames().length == 0);
|
||||
}
|
||||
|
||||
public void testToBufferedImageType() {
|
||||
// Assumes mImage is TYPE_INT_ARGB
|
||||
BufferedImage converted = ImageUtil.toBuffered(mImage, BufferedImage.TYPE_BYTE_INDEXED);
|
||||
BufferedImage convertedToo = ImageUtil.toBuffered(mImage, BufferedImage.TYPE_BYTE_BINARY);
|
||||
|
||||
// Should not be the same
|
||||
assertNotSame(mImage, converted);
|
||||
assertNotSame(mImage, convertedToo);
|
||||
|
||||
// Correct type
|
||||
assertTrue(converted.getType() == BufferedImage.TYPE_BYTE_INDEXED);
|
||||
assertTrue(convertedToo.getType() == BufferedImage.TYPE_BYTE_BINARY);
|
||||
|
||||
// Should have same dimensions
|
||||
assertEquals(mImage.getWidth(), converted.getWidth());
|
||||
assertEquals(mImage.getHeight(), converted.getHeight());
|
||||
|
||||
assertEquals(mImage.getWidth(), convertedToo.getWidth());
|
||||
assertEquals(mImage.getHeight(), convertedToo.getHeight());
|
||||
}
|
||||
|
||||
public void testBrightness() {
|
||||
final BufferedImage original = mOriginal;
|
||||
assertNotNull(original);
|
||||
|
||||
final BufferedImage notBrightened = ImageUtil.toBuffered(ImageUtil.brightness(original, 0f));
|
||||
// Assumed: Images should be equal
|
||||
if (original != notBrightened) { // Don't care to test if images are same
|
||||
for (int y = 0; y < original.getHeight(); y++) {
|
||||
for (int x = 0; x < original.getWidth(); x++) {
|
||||
assertEquals(original.getRGB(x, y), notBrightened.getRGB(x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Assumed: All pixels should be brighter or equal to original
|
||||
final BufferedImage brightened = ImageUtil.toBuffered(ImageUtil.brightness(original, 0.4f));
|
||||
final BufferedImage brightenedMore = ImageUtil.toBuffered(ImageUtil.brightness(original, 0.9f));
|
||||
for (int y = 0; y < original.getHeight(); y++) {
|
||||
for (int x = 0; x < original.getWidth(); x++) {
|
||||
assertTrue(original.getRGB(x, y) <= brightened.getRGB(x, y));
|
||||
assertTrue(brightened.getRGB(x, y) <= brightenedMore.getRGB(x, y));
|
||||
}
|
||||
}
|
||||
|
||||
// Assumed: Image should be all white
|
||||
final BufferedImage brightenedMax = ImageUtil.toBuffered(ImageUtil.brightness(original, 2f));
|
||||
for (int y = 0; y < brightenedMax.getHeight(); y++) {
|
||||
for (int x = 0; x < brightenedMax.getWidth(); x++) {
|
||||
assertEquals(0x00FFFFFF, brightenedMax.getRGB(x, y) & 0x00FFFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
// Assumed: All pixels should be darker or equal to originial
|
||||
final BufferedImage brightenedNegative = ImageUtil.toBuffered(ImageUtil.brightness(original, -0.4f));
|
||||
final BufferedImage brightenedNegativeMore = ImageUtil.toBuffered(ImageUtil.brightness(original, -0.9f));
|
||||
for (int y = 0; y < original.getHeight(); y++) {
|
||||
for (int x = 0; x < original.getWidth(); x++) {
|
||||
assertTrue(original.getRGB(x, y) >= brightenedNegative.getRGB(x, y));
|
||||
assertTrue(brightenedNegative.getRGB(x, y) >= brightenedNegativeMore.getRGB(x, y));
|
||||
}
|
||||
}
|
||||
// Assumed: Image should be all black
|
||||
final BufferedImage brightenedMaxNegative = ImageUtil.toBuffered(ImageUtil.brightness(original, -2f));
|
||||
for (int y = 0; y < brightenedMaxNegative.getHeight(); y++) {
|
||||
for (int x = 0; x < brightenedMaxNegative.getWidth(); x++) {
|
||||
assertEquals(0x0, brightenedMaxNegative.getRGB(x, y) & 0x00FFFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
JFrame frame = new JFrame("Sunflower - brightness");
|
||||
frame.setSize(sunflower.getWidth() * 4, sunflower.getHeight() * 2);
|
||||
|
||||
Canvas canvas = new Canvas() {
|
||||
public void paint(Graphics g) {
|
||||
// Draw original for comparison
|
||||
g.drawImage(original, 0, 0, null);
|
||||
|
||||
// This should look like original
|
||||
g.drawImage(notBrightened, 0, original.getHeight(), null);
|
||||
|
||||
// Different versions
|
||||
g.drawImage(brightened, original.getWidth(), 0, null);
|
||||
g.drawImage(brightenedMore, original.getWidth() * 2, 0, null);
|
||||
g.drawImage(brightenedMax, original.getWidth() * 3, 0, null);
|
||||
|
||||
g.drawImage(brightenedNegative, original.getWidth(), original.getHeight(), null);
|
||||
g.drawImage(brightenedNegativeMore, original.getWidth() * 2, original.getHeight(), null);
|
||||
g.drawImage(brightenedMaxNegative, original.getWidth() * 3, original.getHeight(), null);
|
||||
}
|
||||
};
|
||||
|
||||
frame.getContentPane().add(canvas);
|
||||
frame.setVisible(true);
|
||||
|
||||
assertTrue(true);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
public void testContrast() {
|
||||
final BufferedImage original = mOriginal;
|
||||
|
||||
assertNotNull(original);
|
||||
|
||||
final BufferedImage notContrasted = ImageUtil.toBuffered(ImageUtil.contrast(original, 0f));
|
||||
// Assumed: Images should be equal
|
||||
if (original != notContrasted) { // Don't care to test if images are same
|
||||
for (int y = 0; y < original.getHeight(); y++) {
|
||||
for (int x = 0; x < original.getWidth(); x++) {
|
||||
assertEquals("0 constrast should not change image", original.getRGB(x, y), notContrasted.getRGB(x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Assumed: Contrast should be greater or equal to original
|
||||
final BufferedImage contrasted = ImageUtil.toBuffered(ImageUtil.contrast(original));
|
||||
final BufferedImage contrastedDefault = ImageUtil.toBuffered(ImageUtil.contrast(original, 0.5f));
|
||||
for (int y = 0; y < original.getHeight(); y++) {
|
||||
for (int x = 0; x < original.getWidth(); x++) {
|
||||
int oRGB = original.getRGB(x, y);
|
||||
int cRGB = contrasted.getRGB(x, y);
|
||||
int dRGB = contrastedDefault.getRGB(x, y);
|
||||
|
||||
int oR = oRGB >> 16 & 0xFF;
|
||||
int oG = oRGB >> 8 & 0xFF;
|
||||
int oB = oRGB & 0xFF;
|
||||
|
||||
int cR = cRGB >> 16 & 0xFF;
|
||||
int cG = cRGB >> 8 & 0xFF;
|
||||
int cB = cRGB & 0xFF;
|
||||
|
||||
int dR = dRGB >> 16 & 0xFF;
|
||||
int dG = dRGB >> 8 & 0xFF;
|
||||
int dB = dRGB & 0xFF;
|
||||
|
||||
// RED
|
||||
if (oR < 127) {
|
||||
assertTrue("Contrast should be decreased or same", oR >= cR && cR >= dR);
|
||||
}
|
||||
else {
|
||||
assertTrue("Contrast should be increased or same", oR <= cR && cR <= dR);
|
||||
}
|
||||
// GREEN
|
||||
if (oG < 127) {
|
||||
assertTrue("Contrast should be decreased or same", oG >= cG && cG >= dG);
|
||||
}
|
||||
else {
|
||||
assertTrue("Contrast should be increased or same", oG <= cG && cG <= dG);
|
||||
}
|
||||
// BLUE
|
||||
if (oB < 127) {
|
||||
assertTrue("Contrast should be decreased or same", oB >= cB && cB >= dB);
|
||||
}
|
||||
else {
|
||||
assertTrue("Contrast should be increased or same", oB <= cB && cB <= dB);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// Assumed: Only primary colors (w/b/r/g/b/c/y/m)
|
||||
final BufferedImage contrastedMax = ImageUtil.toBuffered(ImageUtil.contrast(original, 1f));
|
||||
for (int y = 0; y < contrastedMax.getHeight(); y++) {
|
||||
for (int x = 0; x < contrastedMax.getWidth(); x++) {
|
||||
int rgb = contrastedMax.getRGB(x, y);
|
||||
int r = rgb >> 16 & 0xFF;
|
||||
int g = rgb >> 8 & 0xFF;
|
||||
int b = rgb & 0xFF;
|
||||
assertTrue("Max contrast should only produce primary colors", r == 0 || r == 255);
|
||||
assertTrue("Max contrast should only produce primary colors", g == 0 || g == 255);
|
||||
assertTrue("Max contrast should only produce primary colors", b == 0 || b == 255);
|
||||
}
|
||||
}
|
||||
|
||||
// Assumed: Contrasts should be less than or equal to original
|
||||
final BufferedImage contrastedNegative = ImageUtil.toBuffered(ImageUtil.contrast(original, -0.5f));
|
||||
for (int y = 0; y < original.getHeight(); y++) {
|
||||
for (int x = 0; x < original.getWidth(); x++) {
|
||||
int oRGB = original.getRGB(x, y);
|
||||
int cRGB = contrastedNegative.getRGB(x, y);
|
||||
|
||||
int oR = oRGB >> 16 & 0xFF;
|
||||
int oG = oRGB >> 8 & 0xFF;
|
||||
int oB = oRGB & 0xFF;
|
||||
|
||||
int cR = cRGB >> 16 & 0xFF;
|
||||
int cG = cRGB >> 8 & 0xFF;
|
||||
int cB = cRGB & 0xFF;
|
||||
|
||||
// RED
|
||||
if (oR >= 127) {
|
||||
assertTrue("Contrast should be decreased or same", oR >= cR);
|
||||
}
|
||||
else {
|
||||
assertTrue("Contrast should be increased or same", oR <= cR);
|
||||
}
|
||||
// GREEN
|
||||
if (oG >= 127) {
|
||||
assertTrue("Contrast should be decreased or same", oG >= cG);
|
||||
}
|
||||
else {
|
||||
assertTrue("Contrast should be increased or same", oG <= cG);
|
||||
}
|
||||
// BLUE
|
||||
if (oB >= 127) {
|
||||
assertTrue("Contrast should be decreased or same", oB >= cB);
|
||||
}
|
||||
else {
|
||||
assertTrue("Contrast should be increased or same", oB <= cB);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Assumed: All gray (127)!
|
||||
final BufferedImage contrastedMoreNegative = ImageUtil.toBuffered(ImageUtil.contrast(original, -1.0f));
|
||||
for (int y = 0; y < contrastedMoreNegative.getHeight(); y++) {
|
||||
for (int x = 0; x < contrastedMoreNegative.getWidth(); x++) {
|
||||
int rgb = contrastedMoreNegative.getRGB(x, y);
|
||||
int r = rgb >> 16 & 0xFF;
|
||||
int g = rgb >> 8 & 0xFF;
|
||||
int b = rgb & 0xFF;
|
||||
assertTrue("Minimum contrast should be all gray", r == 127 && g == 127 &&b == 127);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
JFrame frame = new JFrame("Sunflower - contrast");
|
||||
frame.setSize(sunflower.getWidth() * 4, sunflower.getHeight() * 2);
|
||||
|
||||
Canvas canvas = new Canvas() {
|
||||
public void paint(Graphics g) {
|
||||
// Draw original for comparison
|
||||
g.drawImage(original, 0, 0, null);
|
||||
|
||||
// This should look like original
|
||||
g.drawImage(notContrasted, 0, original.getHeight(), null);
|
||||
|
||||
// Different versions
|
||||
g.drawImage(contrasted, original.getWidth(), 0, null);
|
||||
g.drawImage(contrastedDefault, original.getWidth() * 2, 0, null);
|
||||
g.drawImage(contrastedMax, original.getWidth() * 3, 0, null);
|
||||
g.drawImage(contrastedNegative, original.getWidth() * 2, original.getHeight(), null);
|
||||
g.drawImage(contrastedMoreNegative, original.getWidth() * 3, original.getHeight(), null);
|
||||
}
|
||||
};
|
||||
|
||||
frame.getContentPane().add(canvas);
|
||||
frame.setVisible(true);
|
||||
|
||||
assertTrue(true);
|
||||
*/
|
||||
}
|
||||
|
||||
public void testSharpen() {
|
||||
final BufferedImage original = mOriginal;
|
||||
|
||||
assertNotNull(original);
|
||||
|
||||
final BufferedImage notSharpened = ImageUtil.sharpen(original, 0f);
|
||||
// Assumed: Images should be equal
|
||||
if (original != notSharpened) { // Don't care to test if images are same
|
||||
for (int y = 0; y < original.getHeight(); y++) {
|
||||
for (int x = 0; x < original.getWidth(); x++) {
|
||||
assertEquals("0 sharpen should not change image", original.getRGB(x, y), notSharpened.getRGB(x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Assumed: Difference between neighbouring pixels should increase for higher sharpen values
|
||||
// Assumed: Dynamics of entire image should not change
|
||||
final BufferedImage sharpened = ImageUtil.sharpen(original);
|
||||
final BufferedImage sharpenedDefault = ImageUtil.sharpen(original, 0.3f);
|
||||
final BufferedImage sharpenedMore = ImageUtil.sharpen(original, 1.3f);
|
||||
|
||||
long diffOriginal = 0;
|
||||
long diffSharpened = 0;
|
||||
long diffDefault = 0;
|
||||
long diffMore = 0;
|
||||
|
||||
long absDiffOriginal = 0;
|
||||
long absDiffSharpened = 0;
|
||||
long absDiffDefault = 0;
|
||||
long absDiffMore = 0;
|
||||
|
||||
for (int y = 0; y < original.getHeight(); y++) {
|
||||
for (int x = 1; x < original.getWidth(); x++) {
|
||||
int oRGB = 0x00FFFFFF & original.getRGB(x, y);
|
||||
int sRGB = 0x00FFFFFF & sharpened.getRGB(x, y);
|
||||
int dRGB = 0x00FFFFFF & sharpenedDefault.getRGB(x, y);
|
||||
int mRGB = 0x00FFFFFF & sharpenedMore.getRGB(x, y);
|
||||
|
||||
int poRGB = 0x00FFFFFF & original.getRGB(x - 1, y);
|
||||
int psRGB = 0x00FFFFFF & sharpened.getRGB(x - 1, y);
|
||||
int pdRGB = 0x00FFFFFF & sharpenedDefault.getRGB(x - 1, y);
|
||||
int pmRGB = 0x00FFFFFF & sharpenedMore.getRGB(x - 1, y);
|
||||
|
||||
diffOriginal += poRGB - oRGB;
|
||||
diffSharpened += psRGB - sRGB;
|
||||
diffDefault += pdRGB - dRGB;
|
||||
diffMore += pmRGB - mRGB;
|
||||
|
||||
absDiffOriginal += Math.abs(poRGB - oRGB);
|
||||
absDiffSharpened += Math.abs(psRGB - sRGB);
|
||||
absDiffDefault += Math.abs(pdRGB - dRGB);
|
||||
absDiffMore += Math.abs(pmRGB - mRGB);
|
||||
}
|
||||
}
|
||||
|
||||
//*
|
||||
showEm(original, notSharpened, sharpened, sharpenedDefault, sharpenedMore, "sharpen");
|
||||
//*/
|
||||
|
||||
// assertEquals("Difference should not change", diffOriginal, diffSharpened);
|
||||
assertTrue("Abs difference should increase", absDiffOriginal < absDiffSharpened);
|
||||
// assertEquals("Difference should not change", diffOriginal, diffDefault);
|
||||
assertTrue("Abs difference should increase", absDiffOriginal < absDiffDefault);
|
||||
// assertEquals("Difference should not change", diffOriginal, diffMore);
|
||||
assertTrue("Abs difference should increase", absDiffOriginal < absDiffMore);
|
||||
// assertEquals("Difference should not change", diffSharpened, diffMore);
|
||||
assertTrue("Abs difference should increase", absDiffSharpened < absDiffMore);
|
||||
}
|
||||
|
||||
private void showEm(final BufferedImage pOriginal, final BufferedImage pNotSharpened, final BufferedImage pSharpened, final BufferedImage pSharpenedDefault, final BufferedImage pSharpenedMore, final String pTitle) {
|
||||
if (pOriginal != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(new Runnable() {
|
||||
public void run() {
|
||||
JFrame frame = new JFrame("Sunflower - " + pTitle);
|
||||
frame.setSize(pOriginal.getWidth() * 4, pOriginal.getHeight() * 2);
|
||||
|
||||
Canvas canvas = new Canvas() {
|
||||
public void paint(Graphics g) {
|
||||
// Draw original for comparison
|
||||
g.drawImage(pOriginal, 0, 0, null);
|
||||
|
||||
// This should look like original
|
||||
g.drawImage(pNotSharpened, 0, pOriginal.getHeight(), null);
|
||||
|
||||
// Different versions
|
||||
g.drawImage(pSharpened, pOriginal.getWidth(), 0, null);
|
||||
g.drawImage(pSharpenedDefault, pOriginal.getWidth() * 2, 0, null);
|
||||
g.drawImage(pSharpenedMore, pOriginal.getWidth() * 3, 0, null);
|
||||
}
|
||||
};
|
||||
|
||||
frame.getContentPane().add(canvas);
|
||||
frame.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
synchronized (ImageUtilTestCase.this) {
|
||||
ImageUtilTestCase.this.notify();
|
||||
}
|
||||
}
|
||||
});
|
||||
frame.setVisible(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
synchronized (ImageUtilTestCase.this) {
|
||||
try {
|
||||
ImageUtilTestCase.this.wait();
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testBlur() {
|
||||
final BufferedImage original = mOriginal;
|
||||
|
||||
assertNotNull(original);
|
||||
|
||||
final BufferedImage notBlurred = ImageUtil.blur(original, 0f);
|
||||
// Assumed: Images should be equal
|
||||
if (original != notBlurred) { // Don't care to test if images are same
|
||||
for (int y = 0; y < original.getHeight(); y++) {
|
||||
for (int x = 0; x < original.getWidth(); x++) {
|
||||
assertEquals("0 blur should not change image", original.getRGB(x, y), notBlurred.getRGB(x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Assumed: Difference between neighbouring pixels should decrease for higher blur values
|
||||
// Assumed: Dynamics of entire image should not change
|
||||
final BufferedImage blurred = ImageUtil.blur(original);
|
||||
final BufferedImage blurredDefault = ImageUtil.blur(original, 1.5f);
|
||||
final BufferedImage blurredMore = ImageUtil.blur(original, 3f);
|
||||
|
||||
long diffOriginal = 0;
|
||||
long diffBlurred = 0;
|
||||
long diffDefault = 0;
|
||||
long diffMore = 0;
|
||||
|
||||
long absDiffOriginal = 0;
|
||||
long absDiffBlurred = 0;
|
||||
long absDiffDefault = 0;
|
||||
long absDiffMore = 0;
|
||||
|
||||
|
||||
for (int y = 0; y < original.getHeight(); y++) {
|
||||
for (int x = 1; x < original.getWidth(); x++) {
|
||||
int oRGB = 0x00FFFFFF & original.getRGB(x, y);
|
||||
int bRGB = 0x00FFFFFF & blurred.getRGB(x, y);
|
||||
int dRGB = 0x00FFFFFF & blurredDefault.getRGB(x, y);
|
||||
int mRGB = 0x00FFFFFF & blurredMore.getRGB(x, y);
|
||||
|
||||
int poRGB = 0x00FFFFFF & original.getRGB(x - 1, y);
|
||||
int pbRGB = 0x00FFFFFF & blurred.getRGB(x - 1, y);
|
||||
int pdRGB = 0x00FFFFFF & blurredDefault.getRGB(x - 1, y);
|
||||
int pmRGB = 0x00FFFFFF & blurredMore.getRGB(x - 1, y);
|
||||
|
||||
diffOriginal += poRGB - oRGB;
|
||||
diffBlurred += pbRGB - bRGB;
|
||||
diffDefault += pdRGB - dRGB;
|
||||
diffMore += pmRGB - mRGB;
|
||||
|
||||
absDiffOriginal += Math.abs(poRGB - oRGB);
|
||||
absDiffBlurred += Math.abs(pbRGB - bRGB);
|
||||
absDiffDefault += Math.abs(pdRGB - dRGB);
|
||||
absDiffMore += Math.abs(pmRGB - mRGB);
|
||||
}
|
||||
}
|
||||
|
||||
showEm(original, notBlurred, blurred, blurredDefault, blurredMore, "blur");
|
||||
|
||||
// assertEquals("Difference should not change", diffOriginal, diffBlurred);
|
||||
assertTrue(String.format("Abs difference should decrease: %s <= %s", absDiffOriginal, absDiffBlurred), absDiffOriginal > absDiffBlurred);
|
||||
// assertEquals("Difference should not change", diffOriginal, diffDefault);
|
||||
assertTrue("Abs difference should decrease", absDiffOriginal > absDiffDefault);
|
||||
// assertEquals("Difference should not change", diffOriginal, diffMore);
|
||||
assertTrue("Abs difference should decrease", absDiffOriginal > absDiffMore);
|
||||
// assertEquals("Difference should not change", diffBlurred, diffMore);
|
||||
assertTrue("Abs difference should decrease", absDiffBlurred > absDiffMore);
|
||||
}
|
||||
|
||||
public void testIndexImage() {
|
||||
BufferedImage sunflower = mOriginal;
|
||||
|
||||
assertNotNull(sunflower);
|
||||
|
||||
BufferedImage image = ImageUtil.createIndexed(sunflower);
|
||||
assertNotNull("Image was null", image);
|
||||
assertTrue(image.getColorModel() instanceof IndexColorModel);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
package com.twelvemonkeys.image;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ImagingOpException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ResampleOpTestCase
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haku $
|
||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/test/java/com/twelvemonkeys/image/ResampleOpTestCase.java#1 $
|
||||
*/
|
||||
public class ResampleOpTestCase extends TestCase {
|
||||
|
||||
protected BufferedImage createImage(final int pWidth, final int pHeigth) {
|
||||
return createImage(pWidth, pHeigth, BufferedImage.TYPE_INT_ARGB);
|
||||
}
|
||||
|
||||
protected BufferedImage createImage(final int pWidth, final int pHeigth, final int pType) {
|
||||
BufferedImage image = new BufferedImage(pWidth, pHeigth, pType);
|
||||
Graphics2D g = image.createGraphics();
|
||||
try {
|
||||
g.setPaint(new GradientPaint(0, 0, Color.RED, pWidth, pHeigth, new Color(0x00000000, true)));
|
||||
g.fillRect(0, 0, pWidth, pHeigth);
|
||||
}
|
||||
finally {
|
||||
g.dispose();
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
public void testCreateImage() {
|
||||
// Sanity test the create method
|
||||
BufferedImage image = createImage(79, 84);
|
||||
assertNotNull(image);
|
||||
assertEquals(79, image.getWidth());
|
||||
assertEquals(84, image.getHeight());
|
||||
}
|
||||
|
||||
private void assertResample(final BufferedImage pImage, final int pWidth, final int pHeight, final int pFilterType) {
|
||||
BufferedImage result = new ResampleOp(pWidth, pHeight, pFilterType).filter(pImage, null);
|
||||
assertNotNull(result);
|
||||
assertEquals(pWidth, result.getWidth());
|
||||
assertEquals(pHeight, result.getHeight());
|
||||
|
||||
result = new ResampleOp(pImage.getWidth(), pImage.getHeight(), pFilterType).filter(createImage(pWidth, pHeight), pImage);
|
||||
assertNotNull(result);
|
||||
assertEquals(pImage.getType(), result.getType());
|
||||
assertSame(pImage, result);
|
||||
assertEquals(pImage.getWidth(), result.getWidth());
|
||||
assertEquals(pImage.getHeight(), result.getHeight());
|
||||
|
||||
result = new ResampleOp(pImage.getWidth(), pImage.getHeight(), pFilterType).filter(createImage(pWidth, pHeight), createImage(pWidth, pHeight, pImage.getType()));
|
||||
assertNotNull(result);
|
||||
assertEquals(pImage.getType(), result.getType());
|
||||
assertEquals(pWidth, result.getWidth());
|
||||
assertEquals(pHeight, result.getHeight());
|
||||
}
|
||||
|
||||
private void assertResampleBufferedImageTypes(final int pFilterType) {
|
||||
List<String> exceptions = new ArrayList<String>();
|
||||
|
||||
// Test all image types in BufferedImage
|
||||
for (int type = BufferedImage.TYPE_INT_ARGB; type <= BufferedImage.TYPE_BYTE_INDEXED; type++) {
|
||||
// TODO: Does not currently work with TYPE_BYTE_GRAY or TYPE_USHORT_GRAY
|
||||
// TODO: FixMe!
|
||||
if ((pFilterType == ResampleOp.FILTER_POINT || pFilterType == ResampleOp.FILTER_TRIANGLE) &&
|
||||
(type == BufferedImage.TYPE_BYTE_GRAY || type == BufferedImage.TYPE_USHORT_GRAY)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BufferedImage image = createImage(10, 10, type);
|
||||
try {
|
||||
assertResample(image, 15, 5, pFilterType);
|
||||
}
|
||||
catch (ImagingOpException e) {
|
||||
// NOTE: It is currently allowed for filters to throw this exception and it is PLATFORM DEPENDENT..
|
||||
System.err.println("WARNING: " + e.getMessage() + ", image: " + image);
|
||||
//e.printStackTrace();
|
||||
}
|
||||
catch (Throwable t) {
|
||||
exceptions.add(t.toString() + ": " + image.toString());
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals("Filter threw exceptions: ", Collections.EMPTY_LIST, exceptions);
|
||||
}
|
||||
|
||||
// 1x1
|
||||
public void testResample1x1Point() {
|
||||
assertResample(createImage(1, 1), 10, 11, ResampleOp.FILTER_POINT);
|
||||
}
|
||||
|
||||
public void testResample1x1Box() {
|
||||
assertResample(createImage(1, 1), 10, 11, ResampleOp.FILTER_BOX);
|
||||
}
|
||||
|
||||
public void testResample1x1Triangle() {
|
||||
assertResample(createImage(1, 1), 19, 13, ResampleOp.FILTER_TRIANGLE);
|
||||
}
|
||||
|
||||
public void testResample1x1Lanczos() {
|
||||
assertResample(createImage(1, 1), 7, 49, ResampleOp.FILTER_LANCZOS);
|
||||
}
|
||||
|
||||
public void testResample1x1Gaussian() {
|
||||
assertResample(createImage(1, 1), 11, 34, ResampleOp.FILTER_GAUSSIAN);
|
||||
}
|
||||
|
||||
public void testResample1x1Sinc() {
|
||||
assertResample(createImage(1, 1), 2, 8, ResampleOp.FILTER_BLACKMAN_SINC);
|
||||
}
|
||||
|
||||
// 2x2
|
||||
public void testResample2x2Point() {
|
||||
assertResample(createImage(2, 2), 10, 11, ResampleOp.FILTER_POINT);
|
||||
}
|
||||
|
||||
public void testResample2x2Box() {
|
||||
assertResample(createImage(2, 2), 10, 11, ResampleOp.FILTER_BOX);
|
||||
}
|
||||
|
||||
public void testResample2x2Triangle() {
|
||||
assertResample(createImage(2, 2), 19, 13, ResampleOp.FILTER_TRIANGLE);
|
||||
}
|
||||
|
||||
public void testResample2x2Lanczos() {
|
||||
assertResample(createImage(2, 2), 7, 49, ResampleOp.FILTER_LANCZOS);
|
||||
}
|
||||
|
||||
public void testResample2x2Gaussian() {
|
||||
assertResample(createImage(2, 2), 11, 34, ResampleOp.FILTER_GAUSSIAN);
|
||||
}
|
||||
|
||||
public void testResample2x2Sinc() {
|
||||
assertResample(createImage(2, 2), 2, 8, ResampleOp.FILTER_BLACKMAN_SINC);
|
||||
}
|
||||
|
||||
// 3x3
|
||||
public void testResample3x3Point() {
|
||||
assertResample(createImage(3, 3), 10, 11, ResampleOp.FILTER_POINT);
|
||||
}
|
||||
|
||||
public void testResample3x3Box() {
|
||||
assertResample(createImage(3, 3), 10, 11, ResampleOp.FILTER_BOX);
|
||||
}
|
||||
|
||||
public void testResample3x3Triangle() {
|
||||
assertResample(createImage(3, 3), 19, 13, ResampleOp.FILTER_TRIANGLE);
|
||||
}
|
||||
|
||||
public void testResample3x3Lanczos() {
|
||||
assertResample(createImage(3, 3), 7, 49, ResampleOp.FILTER_LANCZOS);
|
||||
}
|
||||
|
||||
public void testResample3x3Gaussian() {
|
||||
assertResample(createImage(3, 3), 11, 34, ResampleOp.FILTER_GAUSSIAN);
|
||||
}
|
||||
|
||||
public void testResample3x3Sinc() {
|
||||
assertResample(createImage(3, 3), 2, 8, ResampleOp.FILTER_BLACKMAN_SINC);
|
||||
}
|
||||
|
||||
// 4x4
|
||||
public void testResample4x4Point() {
|
||||
assertResample(createImage(4, 4), 10, 11, ResampleOp.FILTER_POINT);
|
||||
}
|
||||
|
||||
public void testResample4x4Box() {
|
||||
assertResample(createImage(4, 4), 10, 11, ResampleOp.FILTER_BOX);
|
||||
}
|
||||
|
||||
public void testResample4x4Triangle() {
|
||||
assertResample(createImage(4, 4), 19, 13, ResampleOp.FILTER_TRIANGLE);
|
||||
}
|
||||
|
||||
public void testResample4x4Lanczos() {
|
||||
assertResample(createImage(4, 4), 7, 49, ResampleOp.FILTER_LANCZOS);
|
||||
}
|
||||
|
||||
public void testResample4x4Gaussian() {
|
||||
assertResample(createImage(4, 4), 11, 34, ResampleOp.FILTER_GAUSSIAN);
|
||||
}
|
||||
|
||||
public void testResample4x4Sinc() {
|
||||
assertResample(createImage(4, 4), 2, 8, ResampleOp.FILTER_BLACKMAN_SINC);
|
||||
}
|
||||
|
||||
// 20x20
|
||||
public void testResample20x20Point() {
|
||||
assertResample(createImage(20, 20), 10, 11, ResampleOp.FILTER_POINT);
|
||||
}
|
||||
|
||||
public void testResample20x20Box() {
|
||||
assertResample(createImage(20, 20), 10, 11, ResampleOp.FILTER_BOX);
|
||||
}
|
||||
|
||||
public void testResample20x20Triangle() {
|
||||
assertResample(createImage(20, 20), 19, 13, ResampleOp.FILTER_TRIANGLE);
|
||||
}
|
||||
|
||||
public void testResample20x20Lanczos() {
|
||||
assertResample(createImage(20, 20), 7, 49, ResampleOp.FILTER_LANCZOS);
|
||||
}
|
||||
|
||||
public void testResample20x20Gaussian() {
|
||||
assertResample(createImage(20, 20), 11, 34, ResampleOp.FILTER_GAUSSIAN);
|
||||
}
|
||||
|
||||
public void testResample20x20Sinc() {
|
||||
assertResample(createImage(20, 20), 2, 8, ResampleOp.FILTER_BLACKMAN_SINC);
|
||||
}
|
||||
|
||||
// 200x160
|
||||
public void testResample200x160Point() {
|
||||
assertResample(createImage(200, 160), 10, 11, ResampleOp.FILTER_POINT);
|
||||
}
|
||||
|
||||
public void testResample200x160Box() {
|
||||
assertResample(createImage(200, 160), 10, 11, ResampleOp.FILTER_BOX);
|
||||
}
|
||||
|
||||
public void testResample200x160Triangle() {
|
||||
assertResample(createImage(200, 160), 19, 13, ResampleOp.FILTER_TRIANGLE);
|
||||
}
|
||||
|
||||
public void testResample200x160Lanczos() {
|
||||
assertResample(createImage(200, 160), 7, 49, ResampleOp.FILTER_LANCZOS);
|
||||
}
|
||||
|
||||
public void testResample200x160Gaussian() {
|
||||
assertResample(createImage(200, 160), 11, 34, ResampleOp.FILTER_GAUSSIAN);
|
||||
}
|
||||
|
||||
public void testResample200x160Sinc() {
|
||||
assertResample(createImage(200, 160), 2, 8, ResampleOp.FILTER_BLACKMAN_SINC);
|
||||
}
|
||||
|
||||
// Test 10x10 -> 15x5 with different algorithms and types
|
||||
public void testResamplePoint() {
|
||||
assertResampleBufferedImageTypes(ResampleOp.FILTER_POINT);
|
||||
}
|
||||
|
||||
public void testResampleBox() {
|
||||
assertResampleBufferedImageTypes(ResampleOp.FILTER_BOX);
|
||||
}
|
||||
|
||||
public void testResampleTriangle() {
|
||||
assertResampleBufferedImageTypes(ResampleOp.FILTER_TRIANGLE);
|
||||
}
|
||||
|
||||
public void testResampleLanczos() {
|
||||
assertResampleBufferedImageTypes(ResampleOp.FILTER_LANCZOS);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user