【问题标题】:Set Picture into RemoteViews将图片设置为 RemoteViews
【发布时间】:2013-02-09 16:37:28
【问题描述】:

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

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

这个库返回一个 Picture 或 PictureDrawable。

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

我尝试寻找将 Drawable 转换为 Bitmap 的代码,如下所示:

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 的大小并设置适当大小的位图(如果我知道的话)。这是最好的方法吗?我该怎么做?也许有更好的方法我什至不知道?

【问题讨论】:

    标签: android svg bitmap imageview drawable


    【解决方案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 不同。也许他没有按照图书馆的要求将外层命名为“边界”。无论哪种方式,我都设法让库正常工作,尽管必须修改 SVG 画板大小。

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

    【讨论】:

    • 您好,我看过您的袖珍应用,非常好用。该代码是开源的吗?
    【解决方案2】:

    我已经尝试过svg-android,但由于这个原因它对我不起作用。更不用说其严重受限的功能集了。

    使用矢量图形的目的是我可以生成任何合适大小的图像以适应 UI 视图大小。这意味着生成方法必须在运行时接受大小要求,而不是总是使用<svg> 标签中声明的width,height

    因此我 used 原生实现: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 的问题。这也是您的经验还是您无法在正常的 ImageViews 中使用它?我发现这很有效: AssetManager am = c.getAssets(); SVG svg = SVGParser.getSVGFromAsset(am, path); PictureDrawable pictureDrawable = svg.createPictureDrawable(); iconView.setImageDrawable(pictureDrawable);
    • @timothyjc 是的 getPicture()svg-android 从来没有为我工作过。它从来没有渲染过任何东西,你也不能使用所有的 svg 标签。有人确实分叉了回购,并改善了这些问题。但不幸的是,我现在不记得那个 fork repo 的链接了 :( .
    • 不幸的是,在画布上绘图并不能帮助我将 svg 设置为 RemoteViews ImageView afaik。
    【解决方案3】:

    我没有使用过android-svg,但如果它使用香草PictureDrawables,那么它应该只是不使用内在界限的问题。

    尝试以下方法:

    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 中?
    • 好吧,ImageView 获得了位图的所有权,并将在它认为合适的时候重新调整它。也就是说,如果您想避免重新缩放(并且您的层次结构已经膨胀),请使用 ImageView.getMeasuredWidth()(和 *Height())来获取视图的尺寸并渲染适当大小的 SVG。此外,将scaleType 设置为fitXY 以避免重采样。
    • 我尝试了您提供的代码,但图标没有放大到 300 像素。相反,左上角只有更多的空白和一个小图标。
    【解决方案4】:

    你试过 createScaledBitmap 吗?

    createScaledBitmap()

    【讨论】:

    • 我想他使用android-svg 的目的是为了避免模糊的光栅化:)
    • 你说得很好。我想他也可以使用该库对 SVG 进行缩放(不确定缩放是否是正确的术语……因为它实际上是矢量)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-13
    • 2012-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多