Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android上的缩放问题-为什么图片如此笨拙?_Android_2d_Game Development - Fatal编程技术网

Android上的缩放问题-为什么图片如此笨拙?

Android上的缩放问题-为什么图片如此笨拙?,android,2d,game-development,Android,2d,Game Development,我没有2D图形和游戏经验。我通过成百上千的错误和损失的几十个小时自学成才。我从简单的化妆游戏开始。我使用Nexus5X进行开发,屏幕看起来还可以。当我完成一个里程碑时,我试着在大型联想平板电脑和小型三星迷你手机上玩这个游戏。它看起来很可怕 原始矢量PSD文件看起来很完美,PNG导出也没有任何问题。但当我缩放图片时,它是凹凸不平的。我知道是位图。但我在其他地方缩放了另一张图片,看起来不错(两张图片都是32位): 当我玩一些谷歌游戏时,他们从来没有缩放问题。它们是如何实施的?他们使用向量吗?有什

我没有2D图形和游戏经验。我通过成百上千的错误和损失的几十个小时自学成才。我从简单的化妆游戏开始。我使用Nexus5X进行开发,屏幕看起来还可以。当我完成一个里程碑时,我试着在大型联想平板电脑和小型三星迷你手机上玩这个游戏。它看起来很可怕

原始矢量PSD文件看起来很完美,PNG导出也没有任何问题。但当我缩放图片时,它是凹凸不平的。我知道是位图。但我在其他地方缩放了另一张图片,看起来不错(两张图片都是32位):

当我玩一些谷歌游戏时,他们从来没有缩放问题。它们是如何实施的?他们使用向量吗?有什么把戏吗

我把所有东西都放在
资产
文件夹中,虽然花了1MB。我反编译了一些apk,它们没有针对每个分辨率的一组变体。尽管它们可以很好地缩放图片

一些源代码片段:

protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);

    this.w = w;
    this.h = h;
    canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    drawCanvas = new Canvas(canvasBitmap);
}

protected void onDraw(Canvas canvas) {
    if (baseBitmap != null) {
        double scale = Math.min((double) w / (double) figure.getW(), (double) h / (double) figure.getH());
        figure.setScaleRatio(scale);
        int sw = (int) (scale * figure.getW());
        int x = ((w - sw) >> 1);
        figure.setX(x);

        paintDressPart(canvas, figure, figure.getMain());
        if (displayedParts != null) {
            for (DressPart dressPart : figure.getParts()) {
                if (displayedParts.contains(dressPart.getId())) {
                    paintDressPart(canvas, figure, dressPart);
                }
            }
        }
    }
}

private void paintDressPart(Canvas canvas, Figure figure, DressPart part) {
    double scale = figure.getScaleRatio();
    int sh = (int) (scale * part.getH());
    int sw = (int) (scale * part.getW());
    int sdx = (int) (scale * part.getDestX());
    int sdy = (int) (scale * part.getDestY());
    scaledRect.set(figure.getX() + sdx, sdy, figure.getX() + sw + sdx, sh + sdy);
    Rect partRect = part.getRect();
    canvas.drawBitmap(baseBitmap, partRect, scaledRect, canvasPaint);
}
如果您想亲自查看,我在GitHub上准备了完整的项目,以便您可以下载并自己运行:

更新

缩小规模也很糟糕。但多亏了Paavnet的评论,我意识到绘画很重要。请参见图片上的差异:

我在3.2英寸AVD图像上运行了演示应用程序。图片278x786缩放到107x303

十月更新

我重写了应用程序以使用资源文件夹而不是资源。Android缩放图片,然后我重新缩放它。虽然它看起来比我不使用Android资源缩放时更好。资源缩放的图片通常比未缩放的nodpi/资源图片更好


我发现mdpi效果最好。我甚至有xxhdpi图片,它看起来比mdpi更糟糕。我认为即使在xxhdpi设备上也是如此!但这可能是图片绘制不好的问题。Android资源缩放可能会平滑线条边缘。

我面临同样的问题。.缩放没有那么平滑。.最佳标准方法

Bitmap resized = Bitmap.createScaledBitmap(yourBitmap, newWidth, newHeight, true);
您可以在web上找到更优化的大小转换器。但实际上,我使用的最佳解决方案是:

1.使用矢量SVG资源。这是100%完美的工作质量。只需确保SVG元素与android兼容(请参阅:)

优点:

  • 最佳品质
  • 有效尺寸
  • 易于编辑
缺点:

  • 并非所有元素都受支持

2.提供高分辨率图像(xxxhdpi一张就足够了)

优点:

  • 优良品质
缺点:

  • 可能会导致性能问题
我希望这会有帮助

他们使用向量吗

SVG/Vector是一个方便的解决方案,但Vector art需要极高的精度,因此不适用于许多艺术样式。将Vector art用于基本形状很容易,但很难使用SVG符号样式添加简单的细节,尽管可以使用
png、jpeg
轻松添加。您可以观看性能在SVG上设置视频模式,谷歌建议将
SVG
用于图标设计。大多数游戏不会将其用于丰富复杂的图像

因此,我不会选择
SVG
,特别是在小细节在游戏中非常重要的地方

它们是如何实现的?有什么诀窍吗

  • 一种方法是只发布具有单一常规资产支持(MDPI、HDPI)的应用程序,如果屏幕密度需要高分辨率,则向用户显示一个对话框,询问用户是否要下载高分辨率资产

  • 您可以使用
    DisplayMetrics
    ,拥有更高密度的图像,并在运行时根据手机密度要求将其缩小。理想情况下,您应该保持相同的纵横比。在16:9的屏幕上安装4:3的游戏看起来很可怕,但在16:10的屏幕上安装16:9可能没有人注意到

  • 您可以使用此方法轻松获得屏幕的高度和宽度(考虑到您使用的是
    SurfaceView
    作为最佳实践

    要在旋转时获取新的宽度高度,请执行以下操作:

    surfaceChanged(SurfaceHolder支架,int格式,int宽度,int高度)

    该方法提供曲面的宽度/高度,因此现在可以使用:

    Bitmap.createScaledBitmap (Bitmap src, int dstWidth, int dstHeight, boolean filter)
    
    从“位图”类中,根据要绘制的曲面的大小按比例重新调整图像的大小。您可以研究一些技术以找到适当的缩放因子

  • OpenGL、kotlin
    可以为您创建丰富的图形应用程序提供优势。通过这些,您可以控制内存和
    GPU
    性能,这基本上是大多数游戏的基础,此外,您还可以利用
    GPU和本机内存空间更有效地控制渲染,而且还有更多你可以想象,如果你不熟悉这些,这将需要一些时间,但一旦你掌握了,他们可以做很多魔术

  • Webp
    将帮助您将大图像的大小减小到一个相当大的差异。应该尝试Webp。(建议,Webp在某些设备上对图像的alpha通道有点问题,但对于图像大小压缩来说太好了)

  • 结论:使用OpenGL、SurfaceView、NDK以及使用缩放因子高效加载图像实现最佳实践,也应该尝试一下

    您还可以查看
    9patch
    图像,在这些图像中,您可以设置限制,仅缩放图像的一部分,而不是整个图像。这非常有用

    更新:根据建议,如果要使用更高分辨率的图像,请禁用缩放或手动计算缩放因子。祝您好运


    注意:如果你愿意,男士们可以随意编辑这个答案,并提供有效的信息。

    我曾尝试在纵向模式下将图片缩放到全屏,看起来很不错。缩小尺寸会导致细节丢失吗?很多图像缩小算法都是b
    Bitmap.createScaledBitmap (Bitmap src, int dstWidth, int dstHeight, boolean filter)