保存为 GIF 后图像质量下降

2023-12-03

我正在开发一款 iOS 应用程序,它允许用户拍摄一系列照片 - 然后将照片放入动画中并导出为 MP4 和 GIF。

虽然 MP4 呈现源质量,但 GIF 颜色等级是可见的。

这是视觉比较:

GIF: GIF

MP4 MP4

我用于导出为 GIF 的代码:

var dictFile = new NSMutableDictionary();
        var gifDictionaryFile = new NSMutableDictionary();
        gifDictionaryFile.Add(ImageIO.CGImageProperties.GIFLoopCount, NSNumber.FromFloat(0));

        dictFile.Add(ImageIO.CGImageProperties.GIFDictionary, gifDictionaryFile);

        var dictFrame = new NSMutableDictionary();
        var gifDictionaryFrame = new NSMutableDictionary();
        gifDictionaryFrame.Add(ImageIO.CGImageProperties.GIFDelayTime, NSNumber.FromFloat(0f));

        dictFrame.Add(ImageIO.CGImageProperties.GIFDictionary, gifDictionaryFrame);


        InvokeOnMainThread(() =>
    {
        var imageDestination = CGImageDestination.Create(fileURL, MobileCoreServices.UTType.GIF, _images.Length);

        imageDestination.SetProperties(dictFile);

        for (int i = 0; i < this._images.Length; i++)
        {
            imageDestination.AddImage(this._images[i].CGImage, dictFrame);

        }
        imageDestination.Close();
    });

我用于导出为 MP4 的代码:

var videoSettings = new NSMutableDictionary();
            videoSettings.Add(AVVideo.CodecKey, AVVideo.CodecH264);
            videoSettings.Add(AVVideo.WidthKey, NSNumber.FromNFloat(images[0].Size.Width));
            videoSettings.Add(AVVideo.HeightKey, NSNumber.FromNFloat(images[0].Size.Height));

            var videoWriter = new AVAssetWriter(fileURL, AVFileType.Mpeg4, out nsError);
            var writerInput = new AVAssetWriterInput(AVMediaType.Video, new AVVideoSettingsCompressed(videoSettings));

            var sourcePixelBufferAttributes = new NSMutableDictionary();

            sourcePixelBufferAttributes.Add(CVPixelBuffer.PixelFormatTypeKey, NSNumber.FromInt32((int)CVPixelFormatType.CV32ARGB));

            var pixelBufferAdaptor = new AVAssetWriterInputPixelBufferAdaptor(writerInput, sourcePixelBufferAttributes);

            videoWriter.AddInput(writerInput);

            if (videoWriter.StartWriting())
            {
                videoWriter.StartSessionAtSourceTime(CMTime.Zero);

                for (int i = 0; i < images.Length; i++)
                {
                    while (true)
                    {
                        if (writerInput.ReadyForMoreMediaData)
                        {
                            var frameTime = new CMTime(1, 10);
                            var lastTime = new CMTime(1 * i, 10);

                            var presentTime = CMTime.Add(lastTime, frameTime);
                            var pixelBufferImage = PixelBufferFromCGImage(images[i].CGImage, pixelBufferAdaptor);

                            Console.WriteLine(pixelBufferAdaptor.AppendPixelBufferWithPresentationTime(pixelBufferImage, presentTime));
                            break;
                        }
                    }
                }

                writerInput.MarkAsFinished();
                await videoWriter.FinishWritingAsync();

我将不胜感激您的帮助!

亲切的问候,

Andre


这只是我的评论的总结...

我不在你们的平台上编码,所以我只提供通用答案(以及我自己的见解)GIF编码器/解码器编码经验)。

GIF图像格式支持每像素高达 8 位,通过简单编码可实现每像素最多 256 种颜色。廉价的编码器只是将输入图像截断为 256 种或更少的颜色,通常会导致丑陋的像素化结果。提高着色质量GIF我知道有 3 种方法:

  1. 多个框架覆盖屏幕并带有自己的调色板

    只需将图像划分为多个叠加层,每个叠加层都有自己的调色板。这是很慢的(就解码而言,因为您需要为每个图像处理更多帧,这可能会导致某些查看器出现同步错误,并且您需要为每个图像多次处理所有与帧相关的块)。编码本身很快,因为您只需根据颜色或区域/位置将帧分离为多个帧。这里(基于区域/位置)示例:

    multiple palettes

    示例图像取自此处:Wiki

    The GIF支持透明度,因此子框架可以重叠...这种方法可以从物理上增加每个像素的颜色N*256 (or N*255对于透明框架)其中N是每个图像使用的帧或调色板的数量。

  2. 抖动

    抖动是一种在仅使用指定颜色(来自调色板)的情况下近似区域颜色以尽可能接近地匹配颜色的技术。这是快速且易于实现的,但结果有点嘈杂。有关更多信息,请参阅我的一些相关答案:

    • 将 BMP 图像转换为绘图仪的指令集?
    • c# 接受一定量抖动的图像抖动例程?
  3. 更好的色彩量化方法

    廉价的编码器只是将颜色截断为预定义的调色板。通过基于直方图对使用的颜色进行聚类可以获得更好的结果。例如参见:

    • 有效的 gif/图像颜色量化?

    结果通常比抖动好得多,但与抖动相比,编码时间很长......

The #1 and #3可以一起使用以进一步提高质量...

如果您无权访问编码代码或管道,您仍然可以在编码之前转换图像本身,进行量化和调色板计算,并将结果直接加载到GIF编码器应该是可能的(如果GIF您使用的编码器至少有点复杂......)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

保存为 GIF 后图像质量下降 的相关文章

  • iOS - 如何在 swift 中使用 `NSMutableString`

    我已经看过这段 Objective C 代码 但我很难在 swift 中做同样的事情 NSMutableAttributedString res self richTextEditor attributedText mutableCopy
  • 如何找到键盘未覆盖的视图部分(UIModalPresenationStyleFormSheet)?

    我有一个视图控制器 显示带有 UITextView 的视图 并且我想在键盘出现时调整视图的大小 以便 UITextView 不会被键盘覆盖 我几乎在所有情况下都可以正常工作 据我所知 仅当视图控制器以 ModalPresentationSt
  • .showsPhysics 内存泄漏

    我最近花了 5 个小时尝试调试 Spritekit 应用程序中的内存泄漏 应用程序启动后 我注意到内存使用量略有上升 我花了 5 个小时中的 3 个小时挖掘参考资料 了解强与弱的关系ARC https developer apple com
  • `navigator.geolocation.getCurrentPosition()` 在 iOS PWA 上挂起

    我有这个片段 const getCurrentPosition gt new Promise
  • React-native-vision-camera无法访问后面的普通摄像头

    我正在尝试在 iPhone 11 Pro 上使用 普通 相机 我使用反应本机视觉相机 当我运行这段代码时 const devices useCameraDevices const deviceBack devices back consol
  • 如何制作带有 SWIFT 图像的弹出窗口

    我想知道如何制作类似于此示例的弹出窗口 原始窗口充满了按钮 选择这些按钮后将拉出我想要使用的图像 我会简单地创建一个可重用的UIView组件以及作为子视图所需的一切 例如UIImageView为了你的形象 UILabel or a UIBu
  • 如何从 SDK 实现每个会话的 Google Places 自动完成功能?

    是否可以从 Android 和 iOS 应用程序的 place sdk 实现基于会话的自动完成 根据 6 月 11 日生效的新 Google 地图框架定价 对自动完成的请求可以分为基于击键 会话的请求 我找不到描述实施步骤的文档 除了这个参
  • 有关 Swift 编译器选项的文档

    您好 我想开始在 Apple Swift 语言上运行一些微基准测试 然而 我觉得很难找到有关编译器优化的不同选项的适当文档 我读过很多关于其他人的语言微基准的问题和文章 但是如果能有一些关于该主题的可靠文档那就太好了 在最新的测试版中 使用
  • (Kiss)XML xpath 和默认命名空间

    我正在开发一个 iPhone 项目 需要解析一些 xml xml 可能包含也可能不包含默认名称空间 我需要知道如何解析 xml 以防它使用默认命名空间 由于我需要读取和写入 xml 因此我倾向于使用 KissXML 但我愿意接受建议 这是我
  • ios swift parse:从 3 个类收集数据

    我有这样的结构 User CardSet 带有指向 User objectId 的指针 user 和 col name 带有点 cards 的卡片到 Card Set objectId 和列 name 我想选择所有卡数据 包括当前用户的卡集
  • iOS:生成pdf时绘制文本时如何设置字体?

    我在ios应用程序中使用drawpdf函数生成pdf 同时调用nsobject类中的drawtext函数 它根据我指定的框架和字符串清楚地绘制文本 我的代码是 void drawText NSString textToDraw inFram
  • 如何在 Swift 中从 UIColor 获取 RGB 代码(INT)[重复]

    这个问题在这里已经有答案了 我想在 Swift 中获取 UIColor 的 RGB 值 let swiftColor UIColor red 1 green 165 255 blue 0 alpha 1 println RGB Value
  • 从命令行添加 Xcode 开发者帐户

    我正在尝试使用xcodebuild allowProvisioningUpdates在我只能通过命令行访问的计算机 Azure Devops macOS 托管计算机 上 不幸的是 根据man xcodebuild为了使用 allowProv
  • AVAssetExportSession 无法导出从 iCloud 下载的视频

    我正在尝试创建从用户相册中选择的视频的缩小版本 输出的最大尺寸为 720p 因此 在检索视频时 我使用 mediumQualityFormat as the deliveryMode 如果用户设备中不存在原始视频或其中等质量版本 这会导致
  • 调整 UIImage 的大小而不将其完全加载到内存中?

    我正在开发一个应用程序 用户可以在其中尝试加载非常非常大的图像 这些图像首先在表格视图中显示为缩略图 我的原始代码会在大图像上崩溃 因此我重写它以首先将图像直接下载到磁盘 是否有一种已知的方法可以调整磁盘上图像的大小 而无需通过以下方式将其
  • “预期的 ';'在 Swift 下的顶级声明符之后”

    我正在尝试将所有颜色设置在一个 Swift 文件中 该文件可以在我的整个应用程序中使用 下面的代码会导致 import Foundation import UIKit class DotColors let tsblueColor UICo
  • 如何向标准 UIButton 添加徽章? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 是否可以在标准中添加看起来标准的徽章UIButton 如果不支持半原生 那么实现此目的最简单的方法是什么 示例图片 这是 Sascha
  • 在 Swift 中从 Parse 加载图像

    我成功地将数据从 Parse 提取到 swift 中 但我的图像似乎没有按照我的方式工作 在我的 cellForRowAtIndexPath 方法中 我执行以下操作 var event AnyObject eventContainerArr
  • ios - 如何声明静态变量? [复制]

    这个问题在这里已经有答案了 C 中声明的静态变量如下 private const string Host http 80dfgf7c22634nbbfb82339d46 cloudapp net private const string S
  • 隐藏选项卡栏项目并对齐其他选项卡项目

    在我的应用程序中 我有 4 个选项卡栏项目 我正在 XIB 文件中添加这 4 个选项卡栏项目 最初我必须显示 3 个选项卡栏项目 同步后我必须在我的应用程序中显示第 4 个选项卡栏项目 因此 为此 我使用以下代码隐藏第四个选项卡栏项目 se

随机推荐