Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Image scaling #6

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 65 additions & 14 deletions svgandroid/src/com/larvalabs/svgandroid/SVGParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,16 @@ public static SVG getSVGFromInputStream(InputStream svgData) throws SVGParseExce
}

/**
* Parse SVG data from a string.
*
* @param svgData the string containing SVG XML data.
* @return the parsed SVG.
* @throws SVGParseException if there is an error while parsing.
* Parse SVG data from an input stream and scale to the specific size.
* @param svgData
* @param targetWidth
* @param targetHeight
* @return
* @throws SVGParseException
*/
public static SVG getSVGFromString(String svgData) throws SVGParseException {
return SVGParser.parse(new ByteArrayInputStream(svgData.getBytes()), 0, 0, false);
public static SVG getSVGFromInputStream(InputStream svgData, int targetWidth, int targetHeight)
throws SVGParseException {
return SVGParser.parse(svgData, 0, 0, false, targetWidth, targetHeight);
}

/**
Expand Down Expand Up @@ -114,8 +116,9 @@ public static SVG getSVGFromAsset(AssetManager assetMngr, String svgPath) throws
* @return the parsed SVG.
* @throws SVGParseException if there is an error while parsing.
*/
public static SVG getSVGFromInputStream(InputStream svgData, int searchColor, int replaceColor) throws SVGParseException {
return SVGParser.parse(svgData, searchColor, replaceColor, false);
public static SVG getSVGFromInputStream(InputStream svgData, int searchColor, int replaceColor,
int targetWidth, int targetHeight) throws SVGParseException {
return SVGParser.parse(svgData, searchColor, replaceColor, false, targetWidth, targetHeight);
}

/**
Expand Down Expand Up @@ -173,15 +176,16 @@ public static Path parsePath(String pathString) {
return doPath(pathString);
}

private static SVG parse(InputStream in, Integer searchColor, Integer replaceColor, boolean whiteMode) throws SVGParseException {
private static SVG parse(InputStream in, Integer searchColor, Integer replaceColor, boolean whiteMode,
int targetWidth, int targetHeight) throws SVGParseException {
// Util.debug("Parsing SVG...");
try {
long start = System.currentTimeMillis();
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
final Picture picture = new Picture();
SVGHandler handler = new SVGHandler(picture);
SVGHandler handler = new SVGHandler(picture, targetWidth, targetHeight);
handler.setColorSwap(searchColor, replaceColor);
handler.setWhiteMode(whiteMode);
xr.setContentHandler(handler);
Expand All @@ -198,6 +202,10 @@ private static SVG parse(InputStream in, Integer searchColor, Integer replaceCol
}
}

private static SVG parse(InputStream in, Integer searchColor, Integer replaceColor, boolean whiteMode) throws SVGParseException {
return parse(in, searchColor, replaceColor, whiteMode, 0, 0);
}

private static NumberParse parseNumbers(String s) {
//Util.debug("Parsing numbers from: '" + s + "'");
int n = s.length();
Expand Down Expand Up @@ -772,6 +780,8 @@ private static class SVGHandler extends DefaultHandler {

Integer searchColor = null;
Integer replaceColor = null;
int targetWidth;
int targetHeight;

boolean whiteMode = false;

Expand All @@ -787,6 +797,12 @@ private SVGHandler(Picture picture) {
paint.setAntiAlias(true);
}

private SVGHandler(Picture picture, int targetWidth, int targetHeight) {
this(picture);
this.targetWidth = targetWidth;
this.targetHeight = targetHeight;
}

public void setColorSwap(Integer searchColor, Integer replaceColor) {
this.searchColor = searchColor;
this.replaceColor = replaceColor;
Expand Down Expand Up @@ -977,6 +993,41 @@ private void popTransform() {
}
}

/**
* Start recording picture on the canvas.
* If target width and height are set for the canvas
* scale output picture uniformally using by the smallest
* dimention.
* @param imageWidth Width of the SVG image.
* @param imageHeight Height of the SVG image.
* @return
*/
private Canvas beginRecordingPicture(int imageWidth, int imageHeight) {
if(targetWidth == 0 || targetHeight == 0) {
return picture.beginRecording(imageWidth, imageHeight);
} else {
Canvas canvas = picture.beginRecording(targetWidth, targetHeight);
prepareScaledCanvas(canvas, imageWidth, imageHeight);
return canvas;
}
}

private static final void prepareScaledCanvas(Canvas canvas, float imageWidth, float imageHeight) {
final float scaleX = canvas.getWidth() / imageWidth;
final float scaleY = canvas.getHeight() / imageHeight;

if(scaleX > scaleY) {
final float dx = ((scaleX - scaleY) * imageWidth) / 2;
canvas.translate(dx, 0);
canvas.scale(scaleY, scaleY);
} else {
final float dy = ((scaleY - scaleX) * imageHeight) / 2;
canvas.translate(0, dy);
canvas.scale(scaleX, scaleX);
}
}


@Override
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
// Reset paint opacity
Expand All @@ -999,9 +1050,9 @@ public void startElement(String namespaceURI, String localName, String qName, At
return;
}
if (localName.equals("svg")) {
int width = (int) Math.ceil(getFloatAttr("width", atts));
int height = (int) Math.ceil(getFloatAttr("height", atts));
canvas = picture.beginRecording(width, height);
int imageWidth = (int) Math.ceil(getFloatAttr("width", atts));
int imageHeight = (int) Math.ceil(getFloatAttr("height", atts));
canvas = beginRecordingPicture(imageWidth, imageHeight);
} else if (localName.equals("defs")) {
// Ignore
} else if (localName.equals("linearGradient")) {
Expand Down