-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added tshirt rendering code and fonts.
- Loading branch information
Leandro
committed
Aug 9, 2011
1 parent
92cb132
commit bdefbfb
Showing
44 changed files
with
498 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
/eclipse | ||
/tmp | ||
/crud | ||
/.classpath | ||
/.project | ||
/.settings | ||
/crud |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package models; | ||
|
||
import java.awt.Graphics2D; | ||
import java.awt.RenderingHints; | ||
import java.awt.image.BufferedImage; | ||
import java.io.File; | ||
import java.io.FileInputStream; | ||
import java.io.FileNotFoundException; | ||
import java.io.FileOutputStream; | ||
import java.io.IOException; | ||
|
||
import models.design.DesignRenderingService; | ||
import models.design.ImageUtils; | ||
import play.Play; | ||
|
||
public class ThumbnailService { | ||
|
||
private static final String BASE_TSHIRT_PATH = Play.applicationPath + "/assets/base-tshirt.png"; | ||
private static final double ON_SCREEN_DESIGN_WIDTH = 212; | ||
private static final int DESIGN_POSITION_X = 124; | ||
private static final int DESIGN_POSITION_Y = 90; | ||
private static final double THUMBNAIL_SCALE = 0.5; | ||
|
||
private static ThumbnailService instance; | ||
|
||
public static ThumbnailService get() { | ||
if(instance == null) instance = new ThumbnailService(); | ||
return instance; | ||
} | ||
|
||
private ThumbnailService() { | ||
} | ||
|
||
public void generateDesignAndThumbnail(TShirt tShirt) { | ||
BufferedImage designOnTShirt = composeDesignOnTShirtImage(tShirt); | ||
savePicture(tShirt, designOnTShirt); | ||
saveThumbnail(tShirt, designOnTShirt); | ||
} | ||
|
||
private BufferedImage composeDesignOnTShirtImage(TShirt tShirt) { | ||
BufferedImage scaledDesign = getScaledDesign(tShirt); | ||
BufferedImage baseTShirt = getBaseTShirt(); | ||
BufferedImage composite = new BufferedImage(baseTShirt.getWidth(), baseTShirt.getHeight(), BufferedImage.TYPE_INT_ARGB); | ||
Graphics2D graphics = composite.createGraphics(); | ||
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); | ||
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); | ||
graphics.drawImage(baseTShirt, 0, 0, baseTShirt.getWidth(), baseTShirt.getHeight(), null); | ||
graphics.drawImage(scaledDesign, DESIGN_POSITION_X, DESIGN_POSITION_Y, scaledDesign.getWidth(), scaledDesign.getHeight(), null); | ||
return composite; | ||
} | ||
|
||
private BufferedImage getScaledDesign(TShirt tShirt) { | ||
BufferedImage design = DesignRenderingService.get().render(tShirt); | ||
return ImageUtils.scale( | ||
design, | ||
ON_SCREEN_DESIGN_WIDTH / Double.valueOf(design.getWidth())); | ||
} | ||
|
||
private BufferedImage getBaseTShirt() { | ||
File file = new File(BASE_TSHIRT_PATH); | ||
byte[] imageData = new byte[(int) file.length()]; | ||
try { | ||
FileInputStream stream = new FileInputStream(file); | ||
stream.read(imageData); | ||
stream.close(); | ||
} catch (Exception e) { | ||
throw new RuntimeException(e); | ||
} | ||
return ImageUtils.getImage(imageData); | ||
} | ||
|
||
private void saveThumbnail(TShirt tShirt, BufferedImage designOnTShirt) { | ||
BufferedImage thumbnail = ImageUtils.scale(designOnTShirt, THUMBNAIL_SCALE); | ||
writeImageToDisk(thumbnail, tShirt.getThumbnailPath()); | ||
} | ||
|
||
private void savePicture(TShirt tShirt, BufferedImage designOnTShirt) { | ||
writeImageToDisk(designOnTShirt, tShirt.getDesignPath()); | ||
} | ||
|
||
private void writeImageToDisk(BufferedImage image, String path) { | ||
FileOutputStream stream = null; | ||
try { | ||
stream = new FileOutputStream(path); | ||
stream.write(ImageUtils.getBytes(image)); | ||
stream.close(); | ||
} catch (FileNotFoundException e) { | ||
throw new RuntimeException(e); | ||
} catch (IOException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package models.design; | ||
|
||
public abstract class AbstractStamp { | ||
|
||
private double x; | ||
private double y; | ||
private double rotation; | ||
private double scale; | ||
|
||
public AbstractStamp() { | ||
} | ||
|
||
public AbstractStamp(double x, double y, double rotation, double scale) { | ||
this.x = x; | ||
this.y = y; | ||
this.rotation = rotation; | ||
this.scale = scale; | ||
} | ||
|
||
public double getX() { | ||
return x; | ||
} | ||
|
||
public void setX(double x) { | ||
this.x = x; | ||
} | ||
|
||
public double getY() { | ||
return y; | ||
} | ||
|
||
public void setY(double y) { | ||
this.y = y; | ||
} | ||
|
||
public double getRotation() { | ||
return rotation; | ||
} | ||
|
||
public void setRotation(double rotation) { | ||
this.rotation = rotation; | ||
} | ||
|
||
public double getScale() { | ||
return scale; | ||
} | ||
|
||
public void setScale(double scale) { | ||
this.scale = scale; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package models.design; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class Design { | ||
|
||
private String tShirtColor; | ||
private List<AbstractStamp> stamps = new ArrayList<AbstractStamp>(); | ||
|
||
public String getTShirtColor() { | ||
return tShirtColor; | ||
} | ||
|
||
public void setTShirtColor(String tShirtColor) { | ||
this.tShirtColor = tShirtColor; | ||
} | ||
|
||
public List<AbstractStamp> getStamps() { | ||
return stamps; | ||
} | ||
|
||
public void setStamps(List<AbstractStamp> stamps) { | ||
this.stamps = stamps; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package models.design; | ||
|
||
import java.io.StringReader; | ||
import java.util.List; | ||
|
||
import org.dom4j.Document; | ||
import org.dom4j.DocumentException; | ||
import org.dom4j.Element; | ||
import org.dom4j.io.SAXReader; | ||
|
||
import play.libs.Codec; | ||
|
||
public class DesignParser { | ||
|
||
private Document document; | ||
private Design design; | ||
|
||
public static Design parse(String xml) { | ||
try { | ||
return new DesignParser(xml).design; | ||
} catch (DocumentException e) { | ||
throw new RuntimeException("Cannot parse design XML.", e); | ||
} | ||
} | ||
|
||
private DesignParser(String xml) throws DocumentException { | ||
document = new SAXReader().read(new StringReader(xml)); | ||
parseDesign(); | ||
} | ||
|
||
private void parseDesign() { | ||
design = new Design(); | ||
setTShirtColor(); | ||
setStamps(); | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
private void setStamps() { | ||
for(Element element : (List<Element>) document.getRootElement().elements()) { | ||
if(element.getName().equals("imageStamp")) { | ||
design.getStamps().add(parseImageStamp(element)); | ||
} else if(element.getName().equals("textStamp")) { | ||
design.getStamps().add(parseTextStamp(element)); | ||
} | ||
} | ||
} | ||
|
||
private void setTShirtColor() { | ||
design.setTShirtColor(document.getRootElement().attributeValue("tShirtColor")); | ||
} | ||
|
||
private ImageStamp parseImageStamp(Element element) { | ||
ImageStamp imageStamp = new ImageStamp(); | ||
parseAbstractStamp(element, imageStamp); | ||
imageStamp.setImage(Codec.decodeBASE64(element.element("image").getText())); | ||
return imageStamp; | ||
} | ||
|
||
private TextStamp parseTextStamp(Element element) { | ||
TextStamp textStamp = new TextStamp(); | ||
parseAbstractStamp(element, textStamp); | ||
textStamp.setText(element.element("text").getText()); | ||
textStamp.setFont(element.element("font").getText()); | ||
textStamp.setColor(element.element("color").getText()); | ||
return textStamp; | ||
} | ||
|
||
private void parseAbstractStamp(Element element, AbstractStamp stamp) { | ||
stamp.setX(Float.valueOf(element.attributeValue("x"))); | ||
stamp.setY(Float.valueOf(element.attributeValue("y"))); | ||
stamp.setRotation(Float.valueOf(element.attributeValue("rotation"))); | ||
stamp.setScale(Float.valueOf(element.attributeValue("scale"))); | ||
} | ||
|
||
} |
Oops, something went wrong.