图像上的 AndroidSVG 模糊边缘
AndroidSVG fuzzy edges on image
我想在 android 上显示条码。作为输入,我得到 SVG 字符串。作为 SVG 库,我使用 AndroidSVG。我使用了图书馆网站上的示例代码,一切似乎都很好。但是当我放大图像时,我会得到扭曲的边缘(抗锯齿?)。我试图禁用所有标志。但是图像仍然有模糊的边缘。我的代码可能有什么问题?
图片:
试着放大到最大,你会看到模糊的边缘。
代码:
private void loadQRCode(String svgString) {
SVG svg = null;
try {
svg = SVG.getFromString(svgString);
} catch (SVGParseException e) {
e.printStackTrace();
}
if (svg.getDocumentWidth() != -1) {
int widthPx = Utils.pxFromDp(400);
int heightDp = Utils.pxFromDp(300);
svg.setDocumentWidth(widthPx);
svg.setDocumentHeight(heightDp);
int width = (int) Math.ceil(svg.getDocumentWidth());
int height = (int) Math.ceil(svg.getDocumentHeight());
Bitmap newBM = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas bmcanvas = new Canvas(newBM);
final DrawFilter filter = new PaintFlagsDrawFilter(Paint.ANTI_ALIAS_FLAG| Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG, 0);
bmcanvas.setDrawFilter(filter);
barcode.setLayerType(View.LAYER_TYPE_SOFTWARE,null);
bmcanvas.drawRGB(255, 255, 255);
svg.renderToCanvas(bmcanvas);
barcode.setImageBitmap(newBM);
}
}
如果条形的边缘没有正好在像素边界上,您将获得抗锯齿功能。在高分辨率屏幕上,这通常不应该是可见的。
但是,在您的代码中,您将 SVG 渲染为位图并将位图设置为 ImageView。如果该 ImageView 的尺寸大于位图 - 即。大于 400 x 300,则该位图中的抗锯齿像素可能会渲染得更大,因此更明显。
一种解决方案是避免使用位图。请改用 Picture
/PictureDrawable
。这样,无论大小,条形码都将以最高质量呈现。因为矢量图应该是。
按照此页面上的示例进行操作:
http://bigbadaboom.github.io/androidsvg/use_with_ImageView.html
因此您的代码可能如下所示:
private void loadQRCode(String svgString) {
try {
SVG svg = SVG.getFromString(svgString);
barcode.setLayerType(View.LAYER_TYPE_SOFTWARE,null);
Drawable drawable = new PictureDrawable(svg.renderToPicture());
barcode.setImageDrawable(drawable);
} catch (SVGParseException e) {
e.printStackTrace();
}
}
如果出于某种原因您需要使用位图 - 也许您正在缓存它们或其他东西 - 那么您应该注意 ImageView
大小的变化,然后以新的大小重新创建位图。因此位图的大小始终与分配给它的 ImageView
相同。
我想在 android 上显示条码。作为输入,我得到 SVG 字符串。作为 SVG 库,我使用 AndroidSVG。我使用了图书馆网站上的示例代码,一切似乎都很好。但是当我放大图像时,我会得到扭曲的边缘(抗锯齿?)。我试图禁用所有标志。但是图像仍然有模糊的边缘。我的代码可能有什么问题?
图片:
试着放大到最大,你会看到模糊的边缘。
代码:
private void loadQRCode(String svgString) {
SVG svg = null;
try {
svg = SVG.getFromString(svgString);
} catch (SVGParseException e) {
e.printStackTrace();
}
if (svg.getDocumentWidth() != -1) {
int widthPx = Utils.pxFromDp(400);
int heightDp = Utils.pxFromDp(300);
svg.setDocumentWidth(widthPx);
svg.setDocumentHeight(heightDp);
int width = (int) Math.ceil(svg.getDocumentWidth());
int height = (int) Math.ceil(svg.getDocumentHeight());
Bitmap newBM = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas bmcanvas = new Canvas(newBM);
final DrawFilter filter = new PaintFlagsDrawFilter(Paint.ANTI_ALIAS_FLAG| Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG, 0);
bmcanvas.setDrawFilter(filter);
barcode.setLayerType(View.LAYER_TYPE_SOFTWARE,null);
bmcanvas.drawRGB(255, 255, 255);
svg.renderToCanvas(bmcanvas);
barcode.setImageBitmap(newBM);
}
}
如果条形的边缘没有正好在像素边界上,您将获得抗锯齿功能。在高分辨率屏幕上,这通常不应该是可见的。
但是,在您的代码中,您将 SVG 渲染为位图并将位图设置为 ImageView。如果该 ImageView 的尺寸大于位图 - 即。大于 400 x 300,则该位图中的抗锯齿像素可能会渲染得更大,因此更明显。
一种解决方案是避免使用位图。请改用 Picture
/PictureDrawable
。这样,无论大小,条形码都将以最高质量呈现。因为矢量图应该是。
按照此页面上的示例进行操作:
http://bigbadaboom.github.io/androidsvg/use_with_ImageView.html
因此您的代码可能如下所示:
private void loadQRCode(String svgString) {
try {
SVG svg = SVG.getFromString(svgString);
barcode.setLayerType(View.LAYER_TYPE_SOFTWARE,null);
Drawable drawable = new PictureDrawable(svg.renderToPicture());
barcode.setImageDrawable(drawable);
} catch (SVGParseException e) {
e.printStackTrace();
}
}
如果出于某种原因您需要使用位图 - 也许您正在缓存它们或其他东西 - 那么您应该注意 ImageView
大小的变化,然后以新的大小重新创建位图。因此位图的大小始终与分配给它的 ImageView
相同。