简体   繁体   English

缩放画布以在Android中调整SVG的大小

[英]Scaling Canvas to resize SVG in Android

I'm not having much luck wrapping my head around this, so I'm hoping someone can help me out. 我没有太多的运气包围我的头,所以我希望有人可以帮助我。

I'm getting a drawable from an SVG using svg-android, but the drawable isn't scaling to the view. 我使用svg-android从SVG获得了一个drawable,但是drawable没有缩放到视图。 Everything that I've been able to find says I should draw directly to canvas and rescale the canvas, but when I try that it only seems to change the bounds but not scale the image. 我能够找到的所有内容都说我应该直接绘制到画布并重新缩放画布,但是当我尝试它时,它似乎只是改变边界而不是缩放图像。

This is what I've tried so far: 这是我到目前为止所尝试的:

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);

I've also found a function that will create a scaled bitmap, but the image quality is significantly reduced, so I may as well just use scaled PNGs. 我还发现了一个可以创建缩放位图的函数,但图像质量显着降低,所以我也可以使用缩放的PNG。

Obviously I'm missing something, and my lack of experience is making it really frustrating. 显然我错过了一些东西,而我缺乏经验让它变得非常令人沮丧。

What I'd like to be able to do is have svg-android completely re-scale the SVG before pulling a Picture or PictureDrawable out of it, but I can't figure out how to step through the SVGParser, and running multipliers on every coordinate pair would probably be super resource intensive anyway. 希望能够做的就是拉一个图片或PictureDrawable出来之前,有SVG-机器人完全重新缩放SVG,但我无法弄清楚如何通过SVGParser步骤,并在每个正在运行的乘数无论如何,坐标对可能是超级资源密集型的。

[edit] Is the only way to scale and re-draw the Picture and assign that to a view to create custom Views and override OnDraw? [edit]是缩放和重新绘制图片并将其分配给视图以创建自定义视图和覆盖OnDraw的唯一方法吗?

ie

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);

Am I on the right track? 我是在正确的轨道上吗? Canvas c would overwrite the default canvas (which is what I want), wouldn't it? Canvas c会覆盖默认画布(这就是我想要的),不是吗?

I figured it out. 我想到了。 Or at least figured out a method that works. 或者至少想出一个有效的方法。 The answer was staring me in the face in that scaled bitmap function that I didn't like. 答案是在我不喜欢的缩放位图功能中盯着我。 I fundamentally misunderstood how the Picture class and Draw calls work. 我从根本上误解了Picture类和Draw调用是如何工作的。

Code that seems to have pulled it off: 代码似乎已经取消了:

//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);

I can size it to whatever View I want by getting desiredWidth and desiredHeight from getWidth() and getHeight() calls, and setBackground(vectorDrawing) at the end to put it on the View. 我可以通过getWidth()和getHeight()调用获取desiredWidth和desiredHeight以及最后将setBackground(vectorDrawing)放在View上,将其调整为我想要的任何视图。

I had a similar problem and this is what I learned and how I solved it. 我遇到了类似的问题,这就是我学到的以及如何解决它。 First I tried to render my svg directly into a canvas 首先,我尝试将svg直接渲染到画布中

svg.renderToCanvas(canv);

which didn't have the size I wanted. 它没有我想要的尺寸。 Then I tried to resize the image using 然后我尝试使用调整图像大小

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

and

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

but both didn't work, so I started to look at my SVG. 但两者都没有用,所以我开始看看我的SVG。 The problem was that my SVG started like this 问题是我的SVG是这样开始的

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

and it seems impossible, once width and height are set in the svg, to change this in code afterwards. 一旦在svg中设置了宽度和高度,似乎不可能在之后的代码中更改它。 There is also an answer in the AndroidSvgFAQ where they recommend to remove those attributes. AndroidSvgFAQ中还有一个答案,他们建议删除这些属性。 So I changed this to 所以我改成了

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

The viewBox attribute is the frame of my SVG picture, so if now I use the code above viewBox属性是我的SVG图片的框架,所以如果现在我使用上面的代码

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

I get the content of the box with upper left angle at (0,0) and lower right angle at (1200,696) resized such that the width is 200. You can change the behaviour for the ratio initialy it keeps ratios. 我得到了左上角为(0,0)并且右下角为(1200,696)的盒子的内容,其大小调整为宽度为200.您可以最初保持比率来改变比率的行为。 Note that one can omit width, heigth and ViewBox in SVG and set the ViewBox programmatically 请注意,可以省略SVG中的width,heigth和ViewBox,并以编程方式设置ViewBox

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

To get to know more about the ViewBox attribute see W3ViewBox . 要了解有关ViewBox属性的更多信息,请参阅W3ViewBox

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM