Android上的缩放问题-为什么图片如此笨拙?
我没有2D图形和游戏经验。我通过成百上千的错误和损失的几十个小时自学成才。我从简单的化妆游戏开始。我使用Nexus5X进行开发,屏幕看起来还可以。当我完成一个里程碑时,我试着在大型联想平板电脑和小型三星迷你手机上玩这个游戏。它看起来很可怕 原始矢量PSD文件看起来很完美,PNG导出也没有任何问题。但当我缩放图片时,它是凹凸不平的。我知道是位图。但我在其他地方缩放了另一张图片,看起来不错(两张图片都是32位): 当我玩一些谷歌游戏时,他们从来没有缩放问题。它们是如何实施的?他们使用向量吗?有什么把戏吗 我把所有东西都放在Android上的缩放问题-为什么图片如此笨拙?,android,2d,game-development,Android,2d,Game Development,我没有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兼容(请参阅:)
优点:
- 最佳品质
- 有效尺寸
- 易于编辑
- 并非所有元素都受支持
- 优良品质
- 可能会导致性能问题
png、jpeg
轻松添加。您可以观看性能在SVG上设置视频模式,谷歌建议将SVG
用于图标设计。大多数游戏不会将其用于丰富复杂的图像
因此,我不会选择SVG
,特别是在小细节在游戏中非常重要的地方
它们是如何实现的?有什么诀窍吗
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通道有点问题,但对于图像大小压缩来说太好了)9patch
图像,在这些图像中,您可以设置限制,仅缩放图像的一部分,而不是整个图像。这非常有用
更新:根据建议,如果要使用更高分辨率的图像,请禁用缩放或手动计算缩放因子。祝您好运
注意:如果你愿意,男士们可以随意编辑这个答案,并提供有效的信息。我曾尝试在纵向模式下将图片缩放到全屏,看起来很不错。缩小尺寸会导致细节丢失吗?很多图像缩小算法都是b
Bitmap.createScaledBitmap (Bitmap src, int dstWidth, int dstHeight, boolean filter)