SVG export ignores user DPI setting

• May 18, 2017 - 18:54
Reported version
2.2
Type
Functional
Severity
S5 - Suggestion
Status
active
Project

Hello,

I'm using the latest MuseScore 2.1 release and Jojo-Schmitz-batch_export-6a452a1. I can't get SVG to export at anything other than MuseScore's default DPI. I've tried quitting and restarting MuseScore and rebooting macOS (latest).

This was also a bug in earlier versions of the Batch Convert plugin.

I took a quick look at the plugin's code but couldn't find anywhere to change the setting.

Many thanks in advance for any help.


Comments

Thanks for the helpful explanation. I'm trying to launch mscore from Terminal on macOS but get a "command not found" error. I even made a symlink to mscore in /Applications/MuseScore 2.app/Contents/MacOS and moved the symlink to /Users/myusername/bin and set 755 permissions, but still it doesn't run from the command line on my system. (I realize I can enter the full path /Applications/MuseScore 2.app/Contents/MacOS but a simple command line option "mscore" would be really useful.) Thanks in advance for any help.

Status (old) active by design

Let's close this issue as 'by design', but feel free to open a feature request to allow access to these setting for plugin, and a bug report should the command line option not work.

The usual UNIX way would be to add /Applications/MuseScore\ 2.app/Contents/MacOS to PATH:

export PATH=$PATH:/Applications/MuseScore\ 2.app/Contents/MacOS

Thanks for this. I edited the $PATH variable and now I can run mscore from the command line.

May I ask the proper syntax? The following works and doesn't launch the GUI:

mscore -o filename.svg filename.mscz

When I tried to set the DPI, this setting was ignored:

mscore -o filename.svg -r 278 filename.mscz

mscore -r 278 -o filename.svg filename.mscz

I also wish to use the -T option to trim the SVG.

Importantly, MuseScore 2.1 does *not* seem to use the DPI settings from MuseScore's export settings for the batch convert plugin, at least not on my macOS system (latest OS, latest stable MuseScore). That's the reason I submitted this as a bug report. Can you please reopen this bug?

Status (old) by design active

Reopening bug as active, as the "by design" functionality to read the user's DPI setting from the MuseScore settings fails. I've tried many values and quit and restarted the program as well as rebooted my Mac. It may be a macOS issue.

I also set the priority to major since the inability to set DPI is pretty serious (and mission-critical for my application).

Also, the DPI setting doesn't seem to work from the command line either. (It's possible that I don't have the correct syntax, but I've tried seemingly all possible permutations.)

Well, it is not the plugin that has a bug.
And for sure it isn't major...

This should do, but the order shouldn#t matter:
mscore filename.mscz -o filename.svg -r 278 -T 0

How do you tell which DPI settings the resulting SVG has?
Does it work fo PNG?

(and yes, when I looked at the code recently, I got the feeling that this command line option may not work at all, only the preferences setting, at best)

On my system PNG export responds to the DPI setting, but SVG does not. I've tried exaggerated values such as 1000 to test. SVG always outputs the exact same dimensions no matter what setting is used.

I can check the dimensions both in the XML and in Affinity Designer (vector graphics program on macOS).

Any ideas why the DPI setting is being ignored by the plugin?

"(and yes, when I looked at the code recently, I got the feeling that this
command line option may not work at all, only the preferences setting, at
best)"

Importantly, neither the command line option nor the preferences setting work on MuseScore 2.1.0 with Jojo-Schmitz-batch_export-6a452a1 on macOS 10.12.5.

SVG always outputs the exact same dimensions
How do you tell, what line in the SVG to look at?

And this is not the fault of the plugin, a plain File/Export should do the same thing, as does the commandline

Does it work on Linux by chance?

I should also mention that exporting directly from MuseScore (without the batch converter plugin) does read the user-defined DPI preference.

It's at the beginning of the SVG file:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

Width and height are always the same regardless of the DPI setting input.

If the DPI setting worked, the command line option without GUI would be invaluable for my application, since editing SVGs is otherwise terribly complicated. MuseScore outputs nice and clean SVG code.

Hmm, there is only one saveSVG() method and I can only see it working on the trim option, not in any DPI setting.
There are 2 savePNG() methods, only one of these takes DPI as a parameter, the other uses the preferences setting, and that is the one the plugin uses.

OK, width and height match the values in viewbox, is that that you mean? What DPI would then be then?

If I set export DPI (for SVG and PNG) in MuseScore settings to 1000 and then export the same file as SVG directly from MuseScore (i.e., not using the plugin or the command line), this line reads:

svg width="612px" height="792.175px" viewBox="0 0 612 792.175"

This means that MuseScore's built-in export method is indeed reading the DPI setting. Is there any way to get your plugin to read this setting or accept a user-defined value? According to the command line options in the MuseScore documentation it's supposed to read these values:

-r, --image-resolution
"Determines the output resolution for the output to PNG and SVG images in the converter mode. The default resolution is taken from Preferences, Export, PNG/SVG."

Is this just a bug in macOS? Does it work in Linux?

I should mention the irony of having to specify DPI for vector graphics at all. It should be possible to override any default values stored in the SVG's XML using simple HTML tags and width and height attributes, but these overrides are ignored in mobile browsers on iOS for some reason. This has been driving me crazy, and the only solution I can find is to output SVG files with the exact desired DPI embedded in them. I'm therefore really hoping the MuseScore batch converter plugin bug can be fixed.

Just a thought: I've had several MuseScore versions installed, including a recent nightly build. I've deleted all but the new 2.1 stable release from my Applications folder. Is it possible that 2.1 is somehow reading an old settings file from a former version when I run it from the command line? Just brainstorming here.

all 2.x versions share their settings.

I have no reason to believe that only Mac is affected here. Don't have Linux available, but Windows seems affected too

That setting is not exposed to the plugin framework, so plugins can't use it, so there won't be a fix in it. I repeat: MuseScore batch converter plugin doesn't have a bug here!

Sorry, I overlooked something important: When I exported directly from MuseScore, I forgot that there's no trim option. That means the 612px width was for the whole page, not simply the 1 measure in my test file. When I trimmed the SVG, the width was just 60px—just 1px more than the output from the command line, which is surely just incidental.

I tried different DPI values in the preferences and they all output the same result. This means that the bug is in MuseScore 2.1's SVG export—it doesn't appear to be in your batch convert plugin.

Can anyone on the dev team take a look at what might be causing MuseScore to ignore the user-defined DPI setting when exporting SVGs?

"I repeat: MuseScore batch converter plugin doesn't have a bug here!"

Yes, that's what I just concluded too... see my recent post! ;-)

Any idea how to locate the bug in the MuseScore code? The bug is the same ("SVG export ignores user DPI setting") and it appears to be in MuseScore 2.1 itself, not in the batch convert plugin. Since MuseScore has a setting specifically for SVG (and PNG) DPI, clearly this must be a bug.

At least on my latest macOS system this setting is being ignored. I've speculated that maybe it's reading an old settings file on my system, but judging from your reply this seems unlikely. Can anyone else using any OS try outputting SVGs at different DPI settings and see if the resulting XML (SVG files) is identical?

My guess is that this setting simply doesn't apply to SVG, but only to PNG, regardless of the naming in the dialog https://musescore.org/en/handbook/preferences#export
So the real bug might be the wrong text in that Dialog, and not being able to set DPI for SVG is a missing feature...
Same for transparency, I don't think this really applies to SVG, or does it? And the variables are indeeed called preferences.pngTransparent and preferences.pngResolution.

Now that would explain it. It could be an intended but undeveloped feature. Can any developers chime in here?

Still, SVGs are being output at some default DPI value, so surely this must be set somewhere in the code, right?

That's interesting... I was just looking at that file since there was a comment posted yesterday: "export bitmap to svg with lower resolution than original when applicable".

Yes, this is exactly what I'm looking at now. And yes, it would seem to be a contradiction, but unfortunately it turns out different browsers interpret the width and height embedded within SVG code and ignore any attributes added to HTML. This has been driving me mad, since I had also assumed that the whole point of vectors is to be resolution-independent. It looks like the only solution is to format the SVG files with the desired dimensions.

Transparency does work for SVGs exported from MuseScore.

Hopefully someone can figure out the DPI setting, or maybe I'll play around with a custom build if I have to (though I'll probably just mess things up).

There's a preferences.exportPdfDpi variable for the PDF resolution set in the preferences:

pdfWriter.setResolution(preferences.exportPdfDpi);

Still looking for the PNG/SVG resolution variable. It may be converterDpi referenced in line 2388 of this file as part of the savePng method:

return savePng(score, name, false, preferences.pngTransparent, converterDpi, trimMargin, QImage::Format_ARGB32_Premultiplied);

It's not mentioned elsewhere in the file.

I think I found it. Line 2396 defines savePng with options:

bool MuseScore::savePng(Score* score, const QString& name, bool screenshot, bool transparent, double convDpi, int trimMargin, QImage::Format format)
{

Notice "double convDpi".

saveSvg (line 2606) has no such option:

bool MuseScore::saveSvg(Score* score, const QString& saveName)

So if I'm reading the code correctly, your suspicion would be correct that PNG/SVG resolution in the settings should just read PNG resolution, and SVG resolution still needs to be developed.

Of cource does the transparent option not affect the output Resolution (that would be a rather bad bug). The question is whether it influences the transpareny of an SVG?

I got that, the questions is: is it intransparent with that option unset? Is there such a thing as an intransparent SVG? Is there such a thing with MuseScore's SVGs?

Oh, you're right. (Sorry, it's getting late.) I just exported another test file with transparent checked and unchecked and both exported SVGs are transparent. So you found another bug. :-)

I still definitely consider this a bug report since the settings dialog explicitly provides for SVG DPI as well as transparency, and this is also mentioned in the manual and command line options.

(I certainly don't wish to fight over its classification, but I do think it should be changed back.)

That's a shame, as you wouldn't believe how complicated it is to output an SVG with specified DPI and clean XML, or to edit it after the fact. I really hope this can be fixed (from my perspective!) or added soon. In principle it shouldn't be too complicated since a DPI setting is just a multiplier. I'll keep looking at the code and hope I don't mess things up. :-)

I just see that SVG resolution is accessible to the plugin tramework, see mscore/svggenerator.h, line 77
Using SvgGenerator::resolution() return 360 (not 72), setting it using SvgGenerator::setResolution( (int dpi) has no effect though on the resulting SVG that I'd see. But in master branch the SVG export looks very badly broken anyhow.
Comparing with PNG sizes, the SVG seems to be exported at 360 DPI in master.

May need to try this on the 2.1 branch, it may be as simple as just adding a printer.setResolution(converterDpi) in saveSvg().
Transparency would require more work, like adding a white rectangle for the full SVG size in the lowest layer of the SVG

There's also this code in svggenerator.cpp (line 363):

int resolution() { return d_func()->resolution; }
void setResolution(int resolution) {
Q_ASSERT(!isActive());
d_func()->resolution = resolution;
}

Most important is that everything in an SVG is dependent on DPI, so all coordinates, width and height need to scale as the DPI changes. I have no idea how this is all handled by MuseScore or the SVG generator (which I see is borrowed from Nokia under the LGPL license). Hopefully there's a simple variable that can adjust everything at once.

Probably better to discuss this in the Support forum the person who implemented the changes in SVG export is more likely to see there, as are others who participated in the discussion that led to those changes.