Масштабирование холста для изменения размера SVG на Android

У меня нет большой удачи, обволакивающей мою голову вокруг, поэтому я надеюсь, что кто-то может мне помочь.

Я получаю возможность извлекать из SVG с помощью svg-android, но drawable не масштабируется для представления. Все, что я смог найти, говорит, что я должен рисовать непосредственно на холсте и перемасштабировать холст, но когда я пытаюсь сделать это, кажется, только изменение границ, но не масштабирование изображения.

Это то, что я пробовал до сих пор:

ImageView testview = (ImageView)findViewById(R.id.testview);

//Get SVG and convert to drawable
SVG vector = SVGParser.getSVGFromResource(getResources(),R.drawable.testvector);
Drawable test = vector.createPictureDrawable();

testview.setBackground(test);  //displays fine, but won't scale to the dimensions of
                               //the View

//function that clips the image but doesn't scale:
Drawable testTwo = new CustomPictureDrawable(vector.getPicture(), 
(float)0.5, (float)0.5);

testView.setBackground(testTwo);

class CustomPictureDrawable extends PictureDrawable {
   private float scalex, scaley;

public CustomPictureDrawable(Picture picture, float scalex, float scaley) {
    super(picture);
    this.scalex = scalex;
    this.scaley = scaley;
}

@Override
public void draw(Canvas canvas) {
    Matrix original = canvas.getMatrix();
    canvas.scale(scalex, scaley);
    super.draw(canvas);
    canvas.setMatrix(original);
}
}

//doesn't display anything
Picture testThree = vector.getPicture();

Bitmap b = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_4444);
Canvas c = new Canvas(b);

c.drawPicture(testThree, new Rect(0,0,10,10));

testview.draw(c);

Я также нашел функцию, которая создаст масштабированное растровое изображение, но качество изображения значительно уменьшится, поэтому я могу просто использовать масштабированные PNG.

Очевидно, что я что-то упускаю, и мой недостаток опыта делает его очень неприятным.

То, что я хотел бы сделать, это заставить svg-android полностью переустановить SVG, прежде чем вытащить из него картинку или PictureDrawable, но я не могу понять, как пройти через SVGParser и запускать мультипликаторы на каждой координатной паре, вероятно, в любом случае будут сверхресурсами.

[edit] Является единственным способом масштабирования и повторного рисования изображения и назначить его представлению для создания пользовательских представлений и переопределения OnDraw?

то есть.

Picture testThree = vector.getPicture();

Bitmap b = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_4444);
Canvas c = new Canvas(b);

c.drawPicture(testThree, new Rect(0,0,10,10));

//CustomView extends ImageView or Button or whatever with OnDraw overridden and no
//other changes 
CustomView testview = (CustomView)findViewById(R.id.testview); 

testview.OnDraw(c);

Я на правильном пути? Canvas c будет перезаписывать холст по умолчанию (чего я хочу), не так ли?

Ответ 1

Я понял это. Или, по крайней мере, выяснил метод, который работает. Ответ смотрел мне в лицо той масштабированной растровой функцией, которая мне не нравилась. Я принципиально неправильно понял, как работают класс Picture и Draw.

Код, который, кажется, отключил его:

//Get a Picture from the SVG
SVG vector = SVGParser.getSVGfromResource(getResources(), R.raw.testvector);

Picture test = vector.getPicture();

//Redraw the picture to a new size
Bitmap bitmap = Bitmap.createBitmap(desired width, desired height, config);

Canvas canvas = new Canvas(bitmap);

Picture resizePicture = new Picture();

canvas = resizePicture.beginRecording(desiredWidth, desiredGeight);

canvas.drawPicture(test, new Rect(0,0,desiredWidth, desiredHeight);

resizePicture.endRecording();

//get a drawable from resizePicture
Drawable vectorDrawing = new PictureDrawable(resizePicture);

Я могу настроить его на любой вид, который я хочу, получив желаемый ширину и желаемый результат от вызовов getWidth() и getHeight() и setBackground (vectorDrawing) в конце, чтобы поместить его в представление.

Ответ 2

У меня была аналогичная проблема, и это то, что я узнал, и как я ее решил. Сначала я попытался сделать свой SVG прямо на холсте

svg.renderToCanvas(canv);

который не имел размера, который я хотел. Затем я попытался изменить размер изображения, используя

svg.renderToCanvas(canv,new RectF(0,0,200,200));

и

svg.setDocumentWidth(200);
svg.renderToCanvas(canv);

но оба не работали, поэтому я начал смотреть на свой SVG. Проблема состояла в том, что мой SVG начал вот так

<svg width="66.3679625" height="100.4148375" xmlns="http://www.w3.org/2000/svg">

и кажется невозможным, как только ширина и высота установлены в svg, чтобы впоследствии изменить это в коде. Существует также ответ в AndroidSvgFAQ, где они рекомендуют удалить эти атрибуты. Поэтому я изменил это на

 <svg version="1.1" viewBox="0 0 1280 696" xmlns="http://www.w3.org/2000/svg">

Атрибут viewBox - это кадр моего SVG-изображения, поэтому, если теперь я использую код выше

svg.setDocumentWidth(200);
svg.renderToCanvas(canv);

Я получаю содержимое ящика с верхним левым углом в (0,0) и нижнем правом угле при (1200,696), измененное таким образом, что ширина равна 200. Вы можете изменить поведение для отношения initialy, которое сохраняет отношения, Обратите внимание: в SVG можно исключить ширину, вершину и ViewBox и программно настроить ViewBox

svg.setDocumentViewBox(0,0,width,height);

Чтобы узнать больше о атрибуте ViewBox, см. W3ViewBox.