Skip to content

Instantly share code, notes, and snippets.

@bmoliveira
Created November 29, 2018 11:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bmoliveira/ba100f35e5c820ab271dac217f6ee2bf to your computer and use it in GitHub Desktop.
Save bmoliveira/ba100f35e5c820ab271dac217f6ee2bf to your computer and use it in GitHub Desktop.
Fresco setup with SVG
class Usage {
companion object {
fun loadStuff(image: SimpleDraweeView, imageURI: String) {
image.setImageURI(imageURI)
}
}
}
class SetupExample {
companion object {
private fun setupFresco() {
val svgDecoder = ImageDecoderConfig
.newBuilder()
.addDecodingCapability(
FrescoSVGDecoder.SVG_FORMAT,
FrescoSVGDecoder.SvgFormatChecker(),
FrescoSVGDecoder.SvgDecoder())
.build()
val draweeConfig = DraweeConfig.newBuilder()
.addCustomDrawableFactory(FrescoSVGDecoder.SvgDrawableFactory())
.build()
val pipeline = ImagePipelineConfig.newBuilder(this)
.setImageDecoderConfig(svgDecoder)
.build()
Fresco.initialize(this, pipeline, draweeConfig)
}
}
}
public class FrescoSVGDecoder {
public static final ImageFormat SVG_FORMAT = new ImageFormat("SVG_FORMAT", "svg");
// We do not include the closing ">" since there can be additional information
private static final String HEADER_TAG = "<svg";
private static final byte[][] POSSIBLE_HEADER_TAGS =
{ ImageFormatCheckerUtils.asciiBytes("<?xml") };
public static class SvgFormatChecker implements ImageFormat.FormatChecker {
public static final byte[] HEADER = ImageFormatCheckerUtils.asciiBytes(HEADER_TAG);
@Override
public int getHeaderSize() {
return HEADER.length;
}
@Nullable
@Override
public ImageFormat determineFormat(byte[] headerBytes, int headerSize) {
if (headerSize < getHeaderSize()) {
return null;
}
if (ImageFormatCheckerUtils.startsWithPattern(headerBytes, HEADER)) {
return SVG_FORMAT;
}
for (byte[] possibleHeaderTag : POSSIBLE_HEADER_TAGS) {
if (ImageFormatCheckerUtils.startsWithPattern(headerBytes, possibleHeaderTag) &&
ImageFormatCheckerUtils
.indexOfPattern(headerBytes, headerBytes.length, possibleHeaderTag, possibleHeaderTag.length) > -1) {
return SVG_FORMAT;
}
}
return null;
}
}
public static class CloseableSvgImage extends CloseableImage {
private final SVG mSvg;
private boolean mClosed = false;
public CloseableSvgImage(SVG svg) {
mSvg = svg;
}
public SVG getSvg() {
return mSvg;
}
@Override
public int getSizeInBytes() {
return 0;
}
@Override
public void close() {
mClosed = true;
}
@Override
public boolean isClosed() {
return mClosed;
}
@Override
public int getWidth() {
return 0;
}
@Override
public int getHeight() {
return 0;
}
}
/**
* Decodes a SVG_FORMAT image
*/
public static class SvgDecoder implements ImageDecoder {
@Override
public CloseableImage decode(
EncodedImage encodedImage,
int length,
QualityInfo qualityInfo,
ImageDecodeOptions options) {
try {
SVG svg = SVG.getFromInputStream(encodedImage.getInputStream());
return new CloseableSvgImage(svg);
} catch (SVGParseException e) {
e.printStackTrace();
}
return null;
}
}
/**
* SVG drawable factory that creates {@link PictureDrawable}s for SVG images.
*/
public static class SvgDrawableFactory implements DrawableFactory {
@Override
public boolean supportsImageType(CloseableImage image) {
return image instanceof CloseableSvgImage;
}
@Nullable
@Override
public Drawable createDrawable(CloseableImage image) {
return new SvgPictureDrawable(((CloseableSvgImage) image).getSvg());
}
}
public static class SvgPictureDrawable extends PictureDrawable {
private final SVG mSvg;
public SvgPictureDrawable(SVG svg) {
super(null);
mSvg = svg;
}
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
setPicture(mSvg.renderToPicture(bounds.width(), bounds.height()));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment