Vuforia-Unity开发安卓AR应用:截图画质模糊如何优化?
解决Vuforia+Unity安卓AR截图模糊问题
核心问题分析
你当前的代码存在两个关键问题导致截图模糊:
- 直接将UI世界坐标转成int丢失精度,且未考虑屏幕缩放与UI坐标到像素坐标的正确转换
- 未使用Vuforia原生的相机帧数据,而是读取Unity渲染缓冲区的低分辨率画面
具体解决方案
1. 修正UI坐标到屏幕像素坐标的转换
不要直接使用GetWorldCorners的原始世界坐标,需通过UI相机转换为屏幕像素坐标,避免精度丢失:
yield return new WaitForEndOfFrame(); // 获取UI所在的Canvas和相机 Canvas canvas = _objToScreenshot.GetComponentInParent<Canvas>(); Camera uiCamera = canvas.worldCamera ?? Camera.main; // 将RectTransform的世界角点转换为屏幕像素坐标 Vector3[] corners = new Vector3[4]; _objToScreenshot.GetWorldCorners(corners); for (int i = 0; i < 4; i++) { corners[i] = uiCamera.WorldToScreenPoint(corners[i]); } // 计算截图区域的像素范围(避免截断) float minX = Mathf.Min(corners[0].x, corners[1].x, corners[2].x, corners[3].x); float maxX = Mathf.Max(corners[0].x, corners[1].x, corners[2].x, corners[3].x); float minY = Mathf.Min(corners[0].y, corners[1].y, corners[2].y, corners[3].y); float maxY = Mathf.Max(corners[0].y, corners[1].y, corners[2].y, corners[3].y); int width = Mathf.RoundToInt(maxX - minX); int height = Mathf.RoundToInt(maxY - minY); float startX = minX; float startY = minY;
2. 使用Vuforia原生相机帧获取高清画面
Vuforia的视频背景渲染在独立缓冲区,直接用ReadPixels只能读到Unity的低分辨率渲染结果,需调用Vuforia API获取原始相机帧:
// 获取Vuforia高清相机帧(格式为RGB888) CameraImage cameraImage = CameraDevice.Instance.GetCameraImage(PixelFormat.RGB888); if (cameraImage == null || !cameraImage.IsValid()) { Debug.LogError("无法获取Vuforia相机帧"); yield break; } // 计算屏幕坐标到相机帧坐标的比例(解决分辨率不匹配问题) float ratioX = (float)cameraImage.Width / Screen.width; float ratioY = (float)cameraImage.Height / Screen.height; // 转换裁剪区域到相机帧坐标系(注意Vuforia帧的Y轴是从上到下) int cropX = Mathf.RoundToInt(startX * ratioX); int cropY = Mathf.RoundToInt((Screen.height - startY - height) * ratioY); int cropWidth = Mathf.RoundToInt(width * ratioX); int cropHeight = Mathf.RoundToInt(height * ratioY); // 确保裁剪区域在相机帧范围内 cropX = Mathf.Clamp(cropX, 0, cameraImage.Width - cropWidth); cropY = Mathf.Clamp(cropY, 0, cameraImage.Height - cropHeight); // 创建高清裁剪纹理 Texture2D croppedTexture = new Texture2D(cropWidth, cropHeight, TextureFormat.RGB24, false); croppedTexture.SetPixels(cameraImage.Pixels, cropX + cropY * cameraImage.Width, cropWidth, cropHeight); croppedTexture.Apply(); // 保存截图 byte[] pngData = croppedTexture.EncodeToPNG(); string savePath = $"{Application.persistentDataPath}/{System.DateTime.Now:HH-mm-ss dd,MM,yyyy}.png"; System.IO.File.WriteAllBytes(savePath, pngData); // 清理资源 Destroy(croppedTexture);
3. 补充配置优化
- Unity Player设置:
- 安卓平台:在
Player Settings > Resolution and Presentation中,设置Default Orientation为设备原生方向,关闭Optimize Frame Pacing Quality Settings中,将Texture Quality设为Full Res,Anti Aliasing设为Disabled(避免模糊)
- 安卓平台:在
- Vuforia设置:
- 确认
Camera Device Mode为MODE_OPTIMIZE_QUALITY,Focus Mode设为FOCUS_MODE_CONTINUOUSAUTO Video Background的Scale Mode设为FILL,避免画面拉伸导致的模糊
- 确认
内容的提问来源于stack exchange,提问作者Manuja Dila
相关产品推荐
相关产品推荐

