2013-01-05 149 views
10

我没有太多的运气包装我的头,所以我希望有人能帮助我。Scaling Canvas在Android中调整SVG大小

我使用svg-android从SVG中获取drawable,但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,但我无法弄清楚如何穿过SVGParser ,并且在每个坐标对上运行乘法器无论如何都可能是超级资源密集型的。

是唯一缩放和重新绘制图片并将其分配给视图以创建自定义视图并重写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会覆盖默认画布(这是我想要的),不是吗?

回答

8

我想通了。或者至少想出了一种可行的方法。答案是在我不喜欢的缩放位图函数中看到我。我从根本上误解了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)获得desiredWidth和desiredHeight在最后把它放在View上。

+2

假设您的解决方案位于您的自定义视图的onDraw方法中,并且假设您发现不直接调用该方法... ;-)您无需执行任何操作即可创建新的Canvas,或者甚至是位图。在这样做的过程中,使用svg会失去效率优势(与内存相关)。相反,您可以使用传递给onDraw方法的画布调用canvas.drawPicture(vector.getPicture(),new Rect(0,0,width,height))。如果你想让你的视图类更具可扩展性,你还可以添加一个style的属性,指明原始svg的名称,然后... – wkhatch

+0

(2),然后使用String resourceName访问对应于原始名称的资源ID = a.getString(R.styleable.YouViewClassName_yourViewsCustomAttributeName); svgResourceId = getResources()。getIdentifier(resourceName,“raw”,getContext()。getPackageName()); – wkhatch

+0

哦,一个变量是一个TypedArray对象,它允许你访问你为视图指定的所有stylable属性,而且通常是在构造函数中设置的,或者更好的是构造函数调用的一个简单方法。在任何一个主体中,你都可以这样做:final TypedArray a = getContext()。 – wkhatch

6

我有一个类似的问题,这是我学到了什么,我如何解决它。 首先,我想直接呈现我的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"> 

视框属性是我的SVG图像的帧,所以如果我现在使用上面

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

代码中,我得到了盒子与左上角角内容(0,0),并在(1200,696)处调整右下角,使宽度为200.您可以更改比例初始比率的行为。需要注意的是一个可以忽略的宽度,heigth和视框在SVG,并设置视框编程

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

要了解更多有关视框属性看W3ViewBox

+0

工程像黄油! – whitepearl