2013-01-05 7 views
10

나는이 문제를 해결하기 위해 내 머리를 감싸는 데별로 행운이 없다. 그래서 나를 도와 줄 수 있기를 바란다.Canvas를 확장하여 Android에서 SVG 크기 조정

SVG에서 svg-android를 사용하여 드로어 블을 가져오고 있지만 드로어 블이 뷰로 스케일링되지 않습니다. 내가 찾을 수 있었던 모든 것은 캔버스에 직접 그려야하고 캔버스를 다시 조정해야한다고 말하지만, 시도 할 때 경계를 변경하지만 이미지의 크기를 조정하지 않는 것만 같습니다.

내가 지금까지 시도한 것입니다 :

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.

분명히 나는 ​​뭔가를 놓치고 있으며 경험 부족으로 정말 실망 스럽습니다. 내가 할 수있을 같은 을했던 것과

는 그것의 사진 또는 PictureDrawable를 당겨 전에 SVG-안드로이드 완전히 다시 규모에게 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); 

오전 나는 곧 정상 궤도에? 캔버스 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을 얻어서 원하는보기에 크기 수에 보기에 그것을 끝내십시오.

+2

솔루션이 사용자 정의보기의 onDraw 메서드에 있다고 가정하고 해당 메서드를 직접 호출하지 않는다고 판단한 경우 ... ;-) 새 Canvas를 만드는 데 아무 것도 할 필요가 없습니다. 또는 심지어 비트 맵. 그렇게하면 svg를 사용할 때 효율성과 관련된 이점 (메모리 관련)을 잃게됩니다. 대신 onDraw 메서드에 전달 된 캔버스를 사용하여 canvas.drawPicture (vector.getPicture(), 새 Rect (0,0, width, height))를 호출 할 수 있습니다. 뷰 클래스를 확장 가능하게하려면 원시 svg의 이름을 나타내는 스타일 가능한 속성을 추가 한 다음 ... – wkhatch

+0

(2)을 입력 한 다음 String resourceName을 사용하여 원시 이름에 해당하는 리소스 ID에 액세스합니다 = a.getString (R.styleable.YouViewClassName_yourViewsCustomAttributeName); svgResourceId = getResources(). getIdentifier (resourceName, "raw", getContext(). getPackageName()); – wkhatch

+0

아, 그리고 변수는 TypedArray 객체입니다. 뷰에 지정한 스타일 속성을 모두 액세스 할 수 있으며 일반적으로 생성자 중 하나에서 설정하는 것이거나 더 나은 방법으로 생성자가 호출하는 간단한 방법입니다. 둘 중 하나에서 다음과 같은 작업을 수행 할 수 있습니다. final TypedArray a = getContext(). obtainStyledAttributes (attrs, R.styleable.YourCustomViewClassName, defStyle, 0); – wkhatch

6

나는 비슷한 문제가 있었는데 이것이 내가 배운 것과 해결 방법이다. 우선은 내가 원하는 크기를 가지고 있지 않은 캔버스

svg.renderToCanvas(canv); 

에 직접 내 SVG를 렌더링하기 위해 노력했다. 그럼 난

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 그림의 프레임

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

이 변경, 그래서

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

위의 코드를 사용 지금 만약 내가 왼쪽 각도 상자의 함량을 얻을 너비가 200이되도록 (120,096)의 (0,0) 및 (1200,696)의 오른쪽 꼭지각이 조정됩니다. 너비를 유지하는 비율에 대한 동작을 변경할 수 있습니다. 하나는 SVG에서 폭, heigth 및 뷰 박스를 생략하고 뷰 박스가 W3ViewBox를 볼 속성에 대한 자세한 내용을 알 수있는

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

프로그래밍 뷰 박스를 설정할 수 있습니다.

+0

버터처럼 작동합니다! – whitepearl