将图片设置到RemoteViews中

4

我在我的资产文件夹中有一些SVG文件,我需要动态地将它们设置在我的小部件上(ImageView上)。

我正在使用这个库:http://code.google.com/p/svg-android/

这个库返回一个Picture或PictureDrawable。

我能看到在RemoteViews上使用的唯一方法是setImageViewBitmap,显然需要一个位图。

我尝试寻找将Drawable转换为位图的代码,就像这样:

PictureDrawable pictureDrawable = svg.createPictureDrawable();
Bitmap bitmap = Bitmap.createBitmap(pictureDrawable.getIntrinsicWidth(), pictureDrawable.getIntrinsicHeight(), Config.ARGB_8888); 
Canvas canvas = new Canvas(bitmap); 
canvas.drawPicture(pictureDrawable.getPicture()); 
currentBitmap = bitmap;

但位图太小了。当我在Illustrator中创建位图时,我将画板大小设置为65,这也是内在宽度/高度的大小。
我的小部件可以调整大小,因此ImageView的大小是可变的。即使我将宽度和高度静态地设置为一些大数字,例如...
 Bitmap bitmap = Bitmap.createBitmap(300, 300, Config.ARGB_8888); 

如果只创建了一个小图片,那么生成的位图将在下方和右侧都有大量空白。我想我需要以缩放后的值绘制图片,并创建尺寸为300的位图。理想情况下,如果我知道ImageView的大小,则可以在运行时确定正确的位图大小并设置。这是最好的方法吗?如何实现?也许还有更好的方法我不知道?
4个回答

4
我并没有使用过android-svg,但如果它是使用普通的PictureDrawable,那么只需要不使用内部边界即可。
请尝试以下步骤:
PictureDrawable pictureDrawable = svg.createPictureDrawable();
Bitmap bitmap = Bitmap.createBitmap(300, 300, Config.ARGB_8888); 
Canvas canvas = new Canvas(bitmap); 
pictureDrawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
pictureDrawable.draw(canvas); // do not access the Picture directly, that defeats the purpose
currentBitmap = bitmap;

简而言之,使用Drawable而不是它的Picture,并将Drawable的边界设置为整个画布。

好的,谢谢。我是否只需要取一个随机的大尺寸,比如300,然后让RemoteViews上的ImageView将位图大小缩小?没有更好的方法将SVG设置到小部件的ImageView中吗? - timothyjc
好的,一个 ImageView 会接管 Bitmap 并按需要重新调整其大小。话虽如此,如果您想避免重新调整大小(并且已经膨胀了层次结构),则可以使用 ImageView.getMeasuredWidth()(和 *Height())来获取视图的尺寸,并呈现适当大小的 SVG。此外,设置 scaleTypefitXY 可以避免重新采样。 - Delyan
我尝试了您提供的代码,但图标未放大到300像素。相反,只有更多的白色空间和一个微小的图标出现在左上角。 - timothyjc

1
我最终修改了底层画板的大小为300。所有放大方法都无效。因此,我使用的最终代码是我最初发布的那个:
PictureDrawable pictureDrawable = svg.createPictureDrawable();
Bitmap bitmap = Bitmap.createBitmap(pictureDrawable.getIntrinsicWidth(), pictureDrawable.getIntrinsicHeight(), Config.ARGB_8888); 
Canvas canvas = new Canvas(bitmap); 
canvas.drawPicture(pictureDrawable.getPicture()); 
currentBitmap = bitmap;

一旦我有了一个300x300的位图,我就能使用setImageViewBitmap将其设置到RemoteViews中。

这种做法似乎有点违背使用SVG的初衷(至少在小部件方面是如此)。

我的问题与User117的问题不同。也许他没有像库中所需的那样命名外层“bounds”。无论如何,我设法让库正常工作,尽管我不得不修改SVG画板的大小。

希望随着屏幕分辨率的增加,Android很快就会将SVG作为平台的一部分引入。


你好,我已经看到了你的口袋应用程序,使用起来非常好。这个代码是开源的吗? - Kanth

1

我想他使用 android-svg 的目的是为了避免模糊的光栅化 :) - Delyan
你说得很有道理。我想他也可以使用那个库来扩展SVG的大小(不确定“scale”是否是正确的术语,因为它实际上是矢量图)。 - Zerkz

1
我尝试过svg-android,但由于其功能严重受限,因此无法满足我的需求。使用矢量图形的目的是可以生成适合UI视图大小的任何大小的图像。这意味着生成方法必须在运行时接受大小要求,而不总是使用<svg>标签中声明的widthheight
因此,我使用本地实现:libsvg-android,它恰好可以做到这一点。
它直接呈现给定大小的画布:
long objId = SvgRaster.svgAndroidCreate();
SvgRaster.svgAndroidParseBuffer(objId, readString(mInputStream, "UTF-8"));
SvgRaster.svgAndroidSetAntialiasing(objId, true);
SvgRaster.svgAndroidRenderToArea(objId, mCanvas, 0, 0, mWidth, mHeight);

我只在RemoteViews上遇到了这个问题。你有同样的经历吗?还是你无法在普通的ImageView中使用它?我发现这个方法可行:AssetManager am = c.getAssets(); SVG svg = SVGParser.getSVGFromAsset(am, path); PictureDrawable pictureDrawable = svg.createPictureDrawable(); iconView.setImageDrawable(pictureDrawable); - timothyjc
@timothyjc 是的,svg-androidgetPicture() 对我来说从未起作用。它从未呈现任何内容,而且您无法使用所有的 SVG 标签。有人分叉了该存储库,并改善了这些问题。但不幸的是,我现在不记得那个分叉存储库的链接了:(。 - S.D.
很遗憾,将图形绘制到画布上似乎无法帮助我在 RemoteViews ImageView 中设置绘制 SVG。 - timothyjc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接