Skip to content
Snippets Groups Projects
Commit b6e0a571 authored by Gustavo Trott's avatar Gustavo Trott
Browse files

Implements forceRasterizeSlides (force convert presentation to png before svg)...

Implements forceRasterizeSlides (force convert presentation to png before svg) and pngWidthRasterizedSlides (force png width (px))
parent b2174446
No related branches found
No related tags found
No related merge requests found
......@@ -31,6 +31,8 @@ public class SvgImageCreatorImp implements SvgImageCreator {
private long pathsThreshold;
private int convPdfToSvgTimeout = 60;
private int svgResolutionPpi = 300;
private boolean forceRasterizeSlides = false;
private int pngWidthRasterizedSlides = 2048;
private String BLANK_SVG;
@Override
......@@ -93,30 +95,37 @@ public class SvgImageCreatorImp implements SvgImageCreator {
File destsvg = new File(imagePresentationDir.getAbsolutePath() + File.separatorChar + "slide" + page + ".svg");
NuProcessBuilder convertPdfToSvg = createConversionProcess("-svg", page, source, destsvg.getAbsolutePath(),
SvgConversionHandler pHandler = new SvgConversionHandler();
if(this.forceRasterizeSlides == false) {
NuProcessBuilder convertPdfToSvg = createConversionProcess("-svg", page, source, destsvg.getAbsolutePath(),
true);
SvgConversionHandler pHandler = new SvgConversionHandler();
convertPdfToSvg.setProcessListener(pHandler);
convertPdfToSvg.setProcessListener(pHandler);
NuProcess process = convertPdfToSvg.start();
try {
process.waitFor(convPdfToSvgTimeout + 1, TimeUnit.SECONDS);
done = true;
} catch (InterruptedException e) {
log.error("Interrupted Exception while generating SVG slides {}", pres.getName(), e);
}
NuProcess process = convertPdfToSvg.start();
try {
process.waitFor(convPdfToSvgTimeout + 1, TimeUnit.SECONDS);
done = true;
} catch (InterruptedException e) {
log.error("Interrupted Exception while generating SVG slides {}", pres.getName(), e);
}
if(pHandler.isCommandTimeout()) {
log.error("Command execution (convertPdfToSvg) exceeded the {} secs timeout for {} page {}.", convPdfToSvgTimeout, pres.getName(), page);
}
if(pHandler.isCommandTimeout()) {
log.error("Command execution (convertPdfToSvg) exceeded the {} secs timeout for {} page {}.", convPdfToSvgTimeout, pres.getName(), page);
}
if (!done) {
return done;
if (!done) {
return done;
}
}
if (destsvg.length() == 0 || pHandler.numberOfImageTags() > imageTagThreshold
|| pHandler.numberOfPaths() > pathsThreshold) {
if (destsvg.length() == 0 ||
pHandler.numberOfImageTags() > imageTagThreshold ||
pHandler.numberOfPaths() > pathsThreshold ||
this.forceRasterizeSlides) {
// We need t delete the destination file as we are starting a
// new conversion process
if (destsvg.exists()) {
......@@ -125,21 +134,24 @@ public class SvgImageCreatorImp implements SvgImageCreator {
done = false;
Map<String, Object> logData = new HashMap<String, Object>();
logData.put("meetingId", pres.getMeetingId());
logData.put("presId", pres.getId());
logData.put("filename", pres.getName());
logData.put("page", page);
logData.put("convertSuccess", pHandler.isCommandSuccessful());
logData.put("fileExists", destsvg.exists());
logData.put("numberOfImages", pHandler.numberOfImageTags());
logData.put("numberOfPaths", pHandler.numberOfPaths());
logData.put("logCode", "potential_problem_with_svg");
logData.put("message", "Potential problem with generated SVG");
Gson gson = new Gson();
String logStr = gson.toJson(logData);
log.warn(" --analytics-- data={}", logStr);
if(!this.forceRasterizeSlides) {
Map<String, Object> logData = new HashMap<String, Object>();
logData.put("meetingId", pres.getMeetingId());
logData.put("presId", pres.getId());
logData.put("filename", pres.getName());
logData.put("page", page);
logData.put("convertSuccess", pHandler.isCommandSuccessful());
logData.put("fileExists", destsvg.exists());
logData.put("numberOfImages", pHandler.numberOfImageTags());
logData.put("numberOfPaths", pHandler.numberOfPaths());
logData.put("logCode", "potential_problem_with_svg");
logData.put("message", "Potential problem with generated SVG");
Gson gson = new Gson();
String logStr = gson.toJson(logData);
log.warn(" --analytics-- data={}", logStr);
}
File tempPng = null;
String basePresentationame = UUID.randomUUID().toString();
......@@ -148,14 +160,15 @@ public class SvgImageCreatorImp implements SvgImageCreator {
} catch (IOException ioException) {
// We should never fall into this if the server is correctly
// configured
Map<String, Object> logData = new HashMap<String, Object>();
logData = new HashMap<String, Object>();
logData.put("meetingId", pres.getMeetingId());
logData.put("presId", pres.getId());
logData.put("filename", pres.getName());
logData.put("logCode", "problem_with_creating_svg");
logData.put("message", "Unable to create temporary files");
gson = new Gson();
logStr = gson.toJson(logData);
Gson gson = new Gson();
String logStr = gson.toJson(logData);
log.error(" --analytics-- data={}", logStr, ioException);
}
......@@ -178,7 +191,6 @@ public class SvgImageCreatorImp implements SvgImageCreator {
if(tempPng.length() > 0) {
// Step 2: Convert a PNG image to SVG
NuProcessBuilder convertPngToSvg = new NuProcessBuilder(Arrays.asList("timeout", convPdfToSvgTimeout + "s", "convert",
tempPng.getAbsolutePath(), destsvg.getAbsolutePath()));
......@@ -254,12 +266,19 @@ public class SvgImageCreatorImp implements SvgImageCreator {
private NuProcessBuilder createConversionProcess(String format, int page, String source, String destFile,
boolean analyze) {
String rawCommand = "pdftocairo -r " + this.svgResolutionPpi + " " + format + (analyze ? "" : " -singlefile")
+ " -q -f " + String.valueOf(page) + " -l " + String.valueOf(page) + " " + source + " " + destFile;
String rawCommand = "pdftocairo -r " + this.svgResolutionPpi + " " + format + (analyze ? "" : " -singlefile");
//Resize png resolution to avoid too large files
if(format.equals("-png") && this.pngWidthRasterizedSlides != 0) {
rawCommand += " -scale-to-x " + this.pngWidthRasterizedSlides + " -scale-to-y -1 ";
}
rawCommand += " -q -f " + String.valueOf(page) + " -l " + String.valueOf(page) + " " + source + " " + destFile;
if (analyze) {
rawCommand += " && cat " + destFile;
rawCommand += " | egrep 'data:image/png;base64|<path' | sed 's/ / /g' | cut -d' ' -f 1 | sort | uniq -cw 2";
}
return new NuProcessBuilder(Arrays.asList("timeout", convPdfToSvgTimeout + "s", "/bin/sh", "-c", rawCommand));
}
......@@ -314,4 +333,12 @@ public class SvgImageCreatorImp implements SvgImageCreator {
public void setSvgResolutionPpi(int svgResolutionPpi) {
this.svgResolutionPpi = svgResolutionPpi;
}
public void setForceRasterizeSlides(boolean forceRasterizeSlides) {
this.forceRasterizeSlides = forceRasterizeSlides;
}
public void setPngWidthRasterizedSlides(int pngWidthRasterizedSlides) {
this.pngWidthRasterizedSlides = pngWidthRasterizedSlides;
}
}
......@@ -108,6 +108,23 @@ svgConversionTimeout=60
#------------------------------------
svgPresentationResolutionPpi=300
#------------------------------------
# Force conversion of slides to PNG before converting to SVG
## This will solve problems like reported in issue #8835
## Disabled by default as it can affect the quality in zoom
#------------------------------------
forceRasterizeSlides=false
#------------------------------------
# Presentation will be resized to this width (in pixels) when rasterizing (converting to PNG)
## Applied in these situations:
## a) the source can't be converted directly to SVG ;
## b) option "forceRasterizeSlides" is defined as true ;
## To disable this constraint (and keep source resolution) define this property as 0.
#------------------------------------
pngWidthRasterizedSlides=2048
#------------------------------------
# Timeout(secs) to wait for conversion script execution
#------------------------------------
......
......@@ -88,6 +88,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<property name="blankSvg" value="${BLANK_SVG}"/>
<property name="convPdfToSvgTimeout" value="${svgConversionTimeout}"/>
<property name="svgResolutionPpi" value="${svgPresentationResolutionPpi}"/>
<property name="forceRasterizeSlides" value="${forceRasterizeSlides}"/>
<property name="pngWidthRasterizedSlides" value="${pngWidthRasterizedSlides}"/>
</bean>
<bean id="generatedSlidesInfoHelper" class="org.bigbluebutton.presentation.GeneratedSlidesInfoHelperImp"/>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment