You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity开发iPhone拍照游戏:相机画面像素化问题求助

解决Unity iPhone相机渲染像素化&照片模糊问题

嘿,这个问题我之前做AR拍照应用时也踩过坑!核心原因是你直接用Screen.width和Screen.height初始化WebCamTexture,但相机硬件不一定支持屏幕的分辨率——WebCamTexture会自动降级到设备支持的最接近低分辨率档位,这就导致了实时画面像素化、保存的照片模糊。

问题根源拆解

WebCamTexture的构造函数如果传入的分辨率不在硬件支持列表里,它会自动 fallback 到设备能处理的最接近分辨率,而这个分辨率往往远低于iPhone Retina屏幕的原生分辨率(毕竟屏幕是逻辑分辨率,相机是物理硬件分辨率)。

解决方案步骤

  1. 获取相机硬件支持的最高分辨率:每个WebCamDevice都自带availableResolutions属性,里面列出了所有硬件兼容的分辨率,我们直接选尺寸最大的那个。
  2. 用最高分辨率初始化WebCamTexture:替换原来的Screen尺寸参数,确保相机输出原生最高画质。
  3. 保存照片时读取原始像素:不要从UI的RawImage上截取画面,直接读取WebCamTexture的原始像素数据,避免UI缩放带来的画质损失。

修改后的完整代码

using UnityEngine;
using UnityEngine.UI;
using System.IO;

public class PhoneCamera : MonoBehaviour 
{
    private bool camAvailable;
    private Texture defaultBackground;
    public static WebCamTexture backCam { get; set; }
    public RawImage background;
    public AspectRatioFitter fit;

    private void Start () 
    {
        defaultBackground = background.texture;
        WebCamDevice[] devices = WebCamTexture.devices;

        if (devices.Length == 0) 
        {
            Debug.Log ("No camera detected");
            camAvailable = false;
            return;
        }

        // 定位后置相机
        WebCamDevice backDevice = default;
        foreach (var device in devices)
        {
            if (!device.isFrontFacing)
            {
                backDevice = device;
                break;
            }
        }

        if (backDevice.name == "") 
        {
            Debug.Log ("Unable to find back camera");
            return;
        }

        // 筛选相机支持的最高分辨率
        Resolution highestRes = backDevice.availableResolutions[0];
        foreach (Resolution res in backDevice.availableResolutions)
        {
            if (res.width * res.height > highestRes.width * highestRes.height)
            {
                highestRes = res;
            }
        }

        // 用最高分辨率初始化相机纹理
        backCam = new WebCamTexture(backDevice.name, highestRes.width, highestRes.height);
        backCam.Play();
        background.texture = backCam;
        camAvailable = true;
    }

    private void Update () 
    {
        if (!camAvailable) return;

        float ratio = (float)backCam.width / (float)backCam.height;
        fit.aspectRatio = ratio;

        float scaleY = backCam.videoVerticallyMirrored ? -1f : 1f;
        background.rectTransform.localScale = new Vector3(1f, scaleY, 1f);

        int orient = -backCam.videoRotationAngle;
        background.rectTransform.localEulerAngles = new Vector3(0, 0, orient);
    }

    // 新增:一键保存照片到相册的方法
    public void CaptureAndSavePhoto()
    {
        if (!camAvailable || backCam == null) return;

        // 从相机纹理读取原始像素
        Texture2D photoTexture = new Texture2D(backCam.width, backCam.height);
        photoTexture.SetPixels(backCam.GetPixels());
        photoTexture.Apply();

        // 转换为PNG格式并保存
        byte[] photoBytes = photoTexture.EncodeToPNG();
        Destroy(photoTexture);

        string tempPath = Path.Combine(Application.persistentDataPath, "temp_photo.png");
        File.WriteAllBytes(tempPath, photoBytes);
        // 调用原生API保存到相册(需确保已添加相册权限)
        NativeGallery.SaveImageToGallery(tempPath, "MyCameraApp", $"Captured_{System.DateTime.Now:yyyyMMddHHmmss}.png");
    }
}

额外注意事项

  • 权限配置:在iOS的Info.plist里必须添加相机和相册权限描述(NSCameraUsageDescription、NSPhotoLibraryAddUsageDescription),否则应用会直接闪退。
  • 真机测试:编辑器里的相机模拟分辨率和真机差异极大,一定要在iPhone真机上验证效果。
  • 性能平衡:如果你的应用对性能要求很高,可以选择次高分辨率,在画质和内存占用间找平衡。

内容的提问来源于stack exchange,提问作者greyBow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:42:03