2016-12-20 2 views
2

Im разрабатывает приложение iOS, которое позволяет пользователям делать последовательность фотографий - впоследствии фотографии помещаются в анимацию и экспортируются как MP4 и GIF.Изображения теряют качество после сохранения в 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

+1

Может ли быть, что глубина цвета для GIF составляет 256, чтобы компромиссы по цвету были сделаны в формате GIF, где MP4 имеет большую гамму? –

+0

Это, скорее всего, потому, что GIF имеет фиксированную цветовую палитру, поэтому общее количество цветов значительно уменьшается от стандартной 24-битной цветовой палитры RGB. @VanquishedWombat в значительной степени сказал все. – rayryeng

+0

ну, я также попытался сохранить изображение как GIF с фотошопом - там не такие цветовые оценки, как на опубликованном GIF :( – Andre

ответ

1

Это просто реферирования шахтных комментариев ...

Я не код на вашей платформе, так что я только обеспечить общий ответ (и понимание от моих собственных GIF опыт кодирования/декодирования).

Формат изображения GIF поддерживает до 8 бит на пиксель, что соответствует максимальному 256 цветов на пиксель с наивным кодированием. Дешевые кодеры просто обрезают входное изображение до 256 или менее цветов, что обычно приводит к уродливым пиксельным результатам. Для повышения качества окраски в GIF есть 3 подхода я знаю:

  1. Несколько кадров, охватывающий экран с собственными палитрами

    Просто вы разделить изображение на накладки каждый со своей собственной палитрой. Это медленное (в термине декодирования, поскольку вам нужно обработать больше кадров на одно изображение, что может вызвать ошибки синхронизации с некоторыми зрителями, и вам нужно обрабатывать все фрагменты, связанные с фреймом, несколько раз за одно изображение). Сама кодировка выполняется быстро, поскольку вы просто разделяете кадры на основе цветов или региона/положения на несколько кадров. Здесь (область/позиция на основе) пример:

    multiple palettes

    образец изображение взято отсюда: Wiki

    GIF поддерживает прозрачность, так что суб кадры могут пересекаться ... Такой подход физически увеличить количество цветов на пиксель до N*256 (или N*255 для прозрачных кадров), где N - количество кадров или палитр, используемых для каждого изображения.

  2. Dithering

    Дизеринг метод, который приблизительная цвет области, чтобы они соответствовали цветам настолько близко, насколько это возможно при использовании только указанных цветов (из палитры) только. Это быстро и легко реализуемо, но результат довольно шумный. Для получения дополнительной информации см некоторых связанных ответов мой:

  3. Лучше цвета квантование метода

    Дешевые кодеры просто усечение цвета предопределенной палитры. Гораздо лучшие результаты получены путем кластеризации используемых цветов на основе гистограммы. Например см:

    В результате, как правило, гораздо лучше, чем сглаживание, но время кодирования огромен по сравнению с размывания ...

# 1 и # 3 могут использоваться вместе для повышения качества еще больше ...

Если у вас нет доступа к кодирующему коду или конвейеру, вы все равно можете преобразовать изображение перед кодированием, вместо этого сделайте вычисление квантования и палитры и загрузите результат непосредственно в кодировщик GIF, который должен быть возможен (если кодер GIF вы, по крайней мере, немного сложны ...)

Смежные вопросы