DEV Community

James Moberg
James Moberg

Posted on

1 1

Parsing Width/Height from SVG File using ColdFusion

Someone on the Lucee website asked how to get width/height of SVG image file in Lucee. I tend use a lot of SVG images when generating PDFs using WKHTMLTOPDF with ColdFusion 2016-2021 and Lucee. I thought I'd try writing a cross-compatible UDF to parse this information. I've added support for desc, title and id metadata. The dimensions will be pulled from svg.viewBox (if exists) rather than width and height tags as I noticed that these dimensions seemed to be used more often with some generators. (NOTE: While the "S" in SVG means that images "scaleable", the dimensions are still extremely beneficial when embedding so you can explicitly code the dimensions using the correct aspect ratio.)

Some SVG images used decimal width/height values while others used integers. Some also contained a "px" unit. I chose to output a numeric double or integer value without the unit. I also read that the default dimensions used by Chrome was 300x150, so it defaults to these dimensions if nothing can be parsed.

Here's the UDF. Enjoy!

https://gist.github.com/JamoCA/baa454a6a5381e7339548a1f627ce1c3

<--- svgInfo: A cross-compatible ColdFusion UDF to parse and return SVG metadata (width, height, filesize, title, desc, id)
2022-05-23 James Moberg / SunStar Media
Gist: https://gist.github.com/JamoCA/baa454a6a5381e7339548a1f627ce1c3
Blog: https://dev.to/gamesover/parsing-widthheight-from-svg-file-using-coldfusion-ljo
Based on this request: https://dev.lucee.org/t/how-to-get-svg-image-file-width-height-and-size-in-lucee/10231/7
<cfscript>
public struct function svgInfo(required string filepath) hint="I parse and return SVG metadata (width, height, filesize, title, desc, id)" {
local.result = [
"width": javacast("int", 0)
,"height": javacast("int", 0)
,"fileSize": javacast("int", 0)
,"title": ""
,"desc": ""
,"id": ""
];
if (!fileExists(arguments.filepath)){
return local.result;
}
local.javaFile = createObject("java", "java.io.File");
local.fileSize = local.javaFile.init(javacast("string", arguments.filepath));
local.result.fileSize = javacast("int", local.fileSize.length());
local.XmlText = javacast("string", fileRead(arguments.filepath, "UTF-8"));
local.start = findNoCase("<SVG", local.XmlText);
if (local.start gt 0){
local.end = findNoCase(">", local.XmlText, local.start);
local.str = mid(local.XmlText, local.start, (local.end - local.start + 1));
if (!val(local.result.width) && !val(local.result.height) && findNocase("viewBox", local.str)){
local.v = refindNoCase("viewBox\s*=\s*""([\d\.\s,]+)""", local.str, 1, true);
if (arrayLen(local.v.match) gte 2 && listLen(local.v.match[2], " ,") is 4){
local.result.width = val(listGetAt(local.v.match[2], 3, " ,"));
local.result.height = val(listGetAt(local.v.match[2], 4, " ,"));
}
}
if (!val(local.result.width) && refindNoCase("width\s*=\s*""(\d+)", local.str)){
local.w = refindNoCase("width\s*=\s*""(\d+)+", local.str, 1, true);
if (arrayLen(local.w.match) gte 2){
local.result.width = val(local.w.match[2]);
}
}
if (!val(local.result.height) && refindNoCase("height\s*=\s*""(\d+)", local.str)){
local.h = refindNoCase("height\s*=\s*""(\d+)+", local.str, 1, true);
if (arrayLen(local.h.match) gte 2){
local.result.height = val(local.h.match[2]);
}
}
if (refindNoCase("id\s*=\s*""(.+?)""", local.str)){
local.id = refindNoCase("id\s*=\s*""(.+?)""", local.str, 1, true);
if (arrayLen(local.id.match) gte 2){
local.result.id = trim(local.id.match[2]);
}
}
}
local.start = findNoCase("<title>", local.XmlText);
if (local.start gt 0){
local.end = findNoCase("</title>", local.XmlText, local.start);
local.result.desc = trim(mid(local.XmlText, local.start+7, (local.end - local.start - 7)));
}
local.start = findNoCase("<desc>", local.XmlText);
if (local.start gt 0){
local.end = findNoCase("</desc>", local.XmlText, local.start);
local.result.desc = trim(mid(local.XmlText, local.start+6, (local.end - local.start - 6)));
}
local.result.width = (!local.result.width) ? javacast("int", 300) : (fix(local.result.width) is local.result.width) ? javacast("int", local.result.width) : javacast("double", local.result.width);
local.result.height = (!local.result.height) ? javacast("int", 150) : (fix(local.result.height) is local.result.height) ? javacast("int", local.result.height) : javacast("double", local.result.height);
return local.result;
}
</cfscript>
view raw svgInfo.cfm hosted with ā¤ by GitHub

Do your career a big favor. Join DEV. (The website you're on right now)

It takes one minute, it's free, and is worth it for your career.

Get started

Community matters

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

šŸ‘‹ Kindness is contagious

Dive into an ocean of knowledge with this thought-provoking post, revered deeply within the supportive DEV Community. Developers of all levels are welcome to join and enhance our collective intelligence.

Saying a simple "thank you" can brighten someone's day. Share your gratitude in the comments below!

On DEV, sharing ideas eases our path and fortifies our community connections. Found this helpful? Sending a quick thanks to the author can be profoundly valued.

Okay