Glide: SVG file is loading too small.

Created on 19 Feb 2016  路  6Comments  路  Source: bumptech/glide

I've used the code from the sample to load a SVG image into my ImageView that is inside a CardView.

Code:

    GenericRequestBuilder<Uri, InputStream, SVG, PictureDrawable> requestBuilder;

    requestBuilder = Glide.with(mContext)
            .using(Glide.buildStreamModelLoader(Uri.class, mContext), InputStream.class)
            .from(Uri.class)
            .as(SVG.class)
            .transcode(new SvgDrawableTranscoder(), PictureDrawable.class)
            .sourceEncoder(new StreamEncoder())
            .cacheDecoder(new FileToStreamDecoder<>(new SVGDecoder()))
            .decoder(new SVGDecoder())
            .placeholder(R.drawable.modulo)
            .error(R.drawable.banner_error)
            .animate(android.R.anim.fade_in)
            .listener(new SvgSoftwareLayerSetter<Uri>());

    requestBuilder
            .diskCacheStrategy(DiskCacheStrategy.NONE)
            .load(Uri.parse("http://foo.bar/blah"))
            .into(cardHolder.iv_card);

The ImageView have a fixed width of 102dp and a fixed height of 94dp on the XML. But the images are getting smaller than they should after they are being loaded. Am I doing something wrong?

img_20160219_155824

non-library question stale

Most helpful comment

_Sorry, I didn't see the edits. No notifications for that._

No, that's not the best approach, because you're hand-reading the ImageView's size, but the solution is the correct one. Notice that the SvgDecoder.decode method receives width/height parameters. Use that, it's easy: move those three lines from the transcoder into the decoder and that's it. The numbers you get there are pixel sizes of the image requested by Glide, so it actually makes sense to force the document size to that value: for this reason we should leave this open and update the sample with those lines.

I think the best value is LETTERBOX (android:scaleType="fitCenter") instead of STRETCH (android:scaleType="fitXY") to prevent squashing/stretching the loaded images. (For completeness FULLSCREEN is android:scaleType="centerCrop".) For more info see PreserveAspectRatio.

All 6 comments

Off the cuff your svg probably has a fixed size. When I opened my svgs in the browser they resized with it, try yours.

Here's an example:

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-25,-25 550 550">
    <g transform="translate(250, 250)">
        <circle r="250" stroke="black" stroke-width="50" fill="white" />
        <text text-anchor="middle" font-size="400" font-weight="bold" dy="125">?</text>
    </g>
</svg> 

If this doesn't help maybe you need to modify the way SvgDrawableTranscoder handles the Picture supplying additional arguments or custom view box to one of those methods calls.

Just noticed, it does have fixed size. It look like this:

<svg version="1.1" id="Layer_1" xml:space="preserve"
    xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    x="0px" y="0px" width="128px" height="128px" viewBox="0 0 128 128"
    enable-background="new 0 0 128 128">

    <!-- other stuff -->

</svg>

Edit: That's exactly the problem there. The 128px on my screen is equivalent to 32dp. How can I fix that on the SvgDrawableTranscoder?

Edit 2: I did find a workaround. My ImageView has a fixed size, so before I create the transcoder, I "query" that value and pass it to the SvgDrawableTranscoder, then I set the svg document width and height. Like that:

svg.setDocumentWidth(w);
svg.setDocumentHeight(h);
svg.setDocumentPreserveAspectRatio(PreserveAspectRatio.STRETCH);

It seems to be working now, but I'm not sure it's the best approach.

_Sorry, I didn't see the edits. No notifications for that._

No, that's not the best approach, because you're hand-reading the ImageView's size, but the solution is the correct one. Notice that the SvgDecoder.decode method receives width/height parameters. Use that, it's easy: move those three lines from the transcoder into the decoder and that's it. The numbers you get there are pixel sizes of the image requested by Glide, so it actually makes sense to force the document size to that value: for this reason we should leave this open and update the sample with those lines.

I think the best value is LETTERBOX (android:scaleType="fitCenter") instead of STRETCH (android:scaleType="fitXY") to prevent squashing/stretching the loaded images. (For completeness FULLSCREEN is android:scaleType="centerCrop".) For more info see PreserveAspectRatio.

I've moved the solution to the decoder, and it worked just fine. Thanks!

Edit: Maybe the decoder could be created in a way to receive the AspectRatio that the dev wants to use, what do you think? Something like:

private PreserveAspectRatio mode;

public SVGDecoder() {
    mode = PreserveAspectRatio.LETTERBOX;
}

public SVGDecoder(PreserveAspectRatio mode) {
    this.mode = mode;
}

This issue has been automatically marked as stale because it has not had activity in the last seven days. It will be closed if no further activity occurs within the next seven days. Thank you for your contributions.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

r4m1n picture r4m1n  路  3Comments

technoir42 picture technoir42  路  3Comments

Anton111111 picture Anton111111  路  3Comments

kooeasy picture kooeasy  路  3Comments

mttmllns picture mttmllns  路  3Comments