Fin import now works with any color image
This commit is contained in:
parent
ec7368cbbf
commit
9cfea90a52
@ -1,3 +1,7 @@
|
|||||||
|
2012-03-18 Jason Blood
|
||||||
|
|
||||||
|
* Updated importing images to freeform fin sets to work with color images with improved description
|
||||||
|
|
||||||
2012-03-17 Sampo Niskanen
|
2012-03-17 Sampo Niskanen
|
||||||
|
|
||||||
* Released version 12.03
|
* Released version 12.03
|
||||||
|
|||||||
@ -1576,11 +1576,11 @@ GuidedTourSelectionDialog.btn.start = Start tour!
|
|||||||
|
|
||||||
! Custom Fin BMP Importer
|
! Custom Fin BMP Importer
|
||||||
CustomFinImport.button.label = Import from image
|
CustomFinImport.button.label = Import from image
|
||||||
CustomFinImport.badFinImage = Invalid fin image. Must be a black and white image (black for the fin), not touching any side, except the bottom of the image, which is the base of the fin.
|
CustomFinImport.badFinImage = Invalid fin image. Make sure the fin is a solid black or dark color and touching the bottom of the image.
|
||||||
CustomFinImport.errorLoadingFile = Error loading file:
|
CustomFinImport.errorLoadingFile = Error loading file:
|
||||||
CustomFinImport.errorParsingFile = Error parsing fin image:
|
CustomFinImport.errorParsingFile = Error parsing fin image:
|
||||||
CustomFinImport.undo = Import freeform fin set
|
CustomFinImport.undo = Import freeform fin set
|
||||||
CustomFinImport.error.title = Error loading fin profile
|
CustomFinImport.error.title = Error loading fin profile
|
||||||
CustomFinImport.error.badimage = Could not deduce fin shape from image.
|
CustomFinImport.error.badimage = Could not deduce fin shape from image.
|
||||||
CustomFinImport.description = The image must be a black and white image (black for the fin), not touching any side, except the bottom of the image, which is the base of the fin.
|
CustomFinImport.description = The image will be converted internally to black and white image (black for the fin), so make sure you use a solid dark color for the fin, and white or a light color for the background. The fin must be touching the bottom of the image, which is the base of the fin.
|
||||||
|
|
||||||
|
|||||||
@ -34,12 +34,20 @@ public class CustomFinImporter {
|
|||||||
facing = FacingDirections.UP;
|
facing = FacingDirections.UP;
|
||||||
|
|
||||||
if (!validateImage(pic)) {
|
if (!validateImage(pic)) {
|
||||||
throw new LocalizedIOException("CustomFinImport.error.badimage");
|
throw new LocalizedIOException("CustomFinImport.badFinImage");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load the fin
|
||||||
points.add(Coordinate.NUL);
|
points.add(Coordinate.NUL);
|
||||||
loadFin(pic, points);
|
loadFin(pic, points);
|
||||||
optimizePoints(points);
|
|
||||||
|
// Optimize the loaded fin
|
||||||
|
int count;
|
||||||
|
do {
|
||||||
|
count = points.size();
|
||||||
|
optimizePoints(points);
|
||||||
|
} while (count != points.size());
|
||||||
|
|
||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,22 +60,22 @@ public class CustomFinImporter {
|
|||||||
for (int x = 0; x < width; ++x) {
|
for (int x = 0; x < width; ++x) {
|
||||||
for (int y = 0; y < height; ++y) {
|
for (int y = 0; y < height; ++y) {
|
||||||
int pixel = pic.getRGB(x, y) & 0x00FFFFFF; // Clear alpha, we don't care about it
|
int pixel = pic.getRGB(x, y) & 0x00FFFFFF; // Clear alpha, we don't care about it
|
||||||
if ((pixel == 0xFFFFFF) || (pixel == 0)) // black or white only
|
// Convert to black & white
|
||||||
{
|
int red = (pixel & 0x00FF0000) >> 16;
|
||||||
if ((x == 0) || (x == width - 1) || (y == 0)) {
|
int green = (pixel & 0x0000FF00) >> 8;
|
||||||
// Left, right and top must have no black (fin)
|
int blue = (pixel & 0x000000FF);
|
||||||
if (pixel == 0)
|
pixel = (int)(0.299*red + 0.587*green + 0.114*blue);
|
||||||
return false;
|
if (pixel > 200)
|
||||||
} else if (y == height - 1) {
|
pixel = 0xFFFFFF; // White
|
||||||
if (pixel == 0) {
|
else
|
||||||
bottomEdgeFound = true;
|
pixel = 0; // Black
|
||||||
if (startX == -1)
|
pic.setRGB(x, y, pixel);
|
||||||
startX = x;
|
if (y == height - 1) {
|
||||||
}
|
if (pixel == 0) {
|
||||||
|
bottomEdgeFound = true;
|
||||||
|
if (startX == -1)
|
||||||
|
startX = x;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// Found something other than a black or white pixel
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,11 +83,11 @@ public class CustomFinImporter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void loadFin(BufferedImage pic, ArrayList<Coordinate> points) {
|
private void loadFin(BufferedImage pic, ArrayList<Coordinate> points) {
|
||||||
boolean calledTurnedAround = false;
|
|
||||||
int height = pic.getHeight();
|
int height = pic.getHeight();
|
||||||
|
Boolean offBottom = false;
|
||||||
|
|
||||||
currentX = startX;
|
currentX = startX;
|
||||||
currentY = pic.getHeight() - 1;
|
currentY = height - 1;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (checkLeftIsFin(pic, currentX, currentY))
|
if (checkLeftIsFin(pic, currentX, currentY))
|
||||||
@ -90,19 +98,17 @@ public class CustomFinImporter {
|
|||||||
rotateRight();
|
rotateRight();
|
||||||
else {
|
else {
|
||||||
turnAround();
|
turnAround();
|
||||||
calledTurnedAround = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
moveForward(pic);
|
moveForward(pic);
|
||||||
|
if (currentY < height - 1)
|
||||||
|
offBottom = true;
|
||||||
if (pixelIsFin(pic, currentX, currentY)) {
|
if (pixelIsFin(pic, currentX, currentY)) {
|
||||||
if (!calledTurnedAround) {
|
double x = (currentX - startX) * 0.001;
|
||||||
double x = (currentX - startX) * 0.001;
|
double y = (height - currentY - 1) * 0.001;
|
||||||
double y = (height - currentY - 1) * 0.001;
|
points.add(new Coordinate(x, y));
|
||||||
points.add(new Coordinate(x, y));
|
|
||||||
} else
|
|
||||||
calledTurnedAround = false;
|
|
||||||
}
|
}
|
||||||
} while (currentY < height - 1 && currentY >= 0);
|
} while ((!offBottom) || (currentY < height - 1 && currentY >= 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean pixelIsFin(BufferedImage pic, int x, int y) {
|
private boolean pixelIsFin(BufferedImage pic, int x, int y) {
|
||||||
@ -210,18 +216,20 @@ public class CustomFinImporter {
|
|||||||
int startIx;
|
int startIx;
|
||||||
ListIterator<Coordinate> start, entry, entry2;
|
ListIterator<Coordinate> start, entry, entry2;
|
||||||
Coordinate startPoint, endPoint, testPoint;
|
Coordinate startPoint, endPoint, testPoint;
|
||||||
|
Boolean removedSection;
|
||||||
|
|
||||||
startIx = 0;
|
startIx = 0;
|
||||||
start = points.listIterator();
|
start = points.listIterator();
|
||||||
startPoint = start.next();
|
startPoint = start.next();
|
||||||
while ((start.hasNext()) && (startPoint != points.get(points.size() - 1))) {
|
while ((start.hasNext()) && (startPoint != points.get(points.size() - 1))) {
|
||||||
|
removedSection = false;
|
||||||
entry = points.listIterator(points.size());
|
entry = points.listIterator(points.size());
|
||||||
endPoint = entry.previous();
|
endPoint = entry.previous();
|
||||||
for (; endPoint != startPoint; endPoint = entry.previous()) {
|
for (; endPoint != startPoint; endPoint = entry.previous()) {
|
||||||
entry2 = points.listIterator(start.nextIndex());
|
entry2 = points.listIterator(start.nextIndex());
|
||||||
testPoint = entry2.next();
|
testPoint = entry2.next();
|
||||||
for (; testPoint != endPoint; testPoint = entry2.next()) {
|
for (; testPoint != endPoint; testPoint = entry2.next()) {
|
||||||
if (pointDistanceFromLine(startPoint, endPoint, testPoint) > 0.001) {
|
if (pointDistanceFromLine(startPoint, endPoint, testPoint) > 0.0008) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -239,10 +247,11 @@ public class CustomFinImporter {
|
|||||||
startIx = nextIx;
|
startIx = nextIx;
|
||||||
start = points.listIterator(startIx);
|
start = points.listIterator(startIx);
|
||||||
startPoint = start.next();
|
startPoint = start.next();
|
||||||
|
removedSection = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (endPoint == startPoint) {
|
if ((!removedSection) && (endPoint == startPoint)) {
|
||||||
startIx = start.nextIndex();
|
startIx = start.nextIndex();
|
||||||
if (start.hasNext())
|
if (start.hasNext())
|
||||||
startPoint = start.next();
|
startPoint = start.next();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user