/// <summary>
 /// 将图片转码为base64字符串
 /// </summary>
 /// <param name="image"></param>
 /// <param name="format"></param>
 /// <returns></returns>
 public static string Encode(this Image image,
                             ImageFormat?format = default)
 {
     using var memory = new MemoryStream();
     image.Save(memory, format ?? image.RawFormat);
     return(Convert.ToBase64String(memory.ToArray()));
 }
示例#2
0
        private ImageFormat GetOutputFormat(ImageRequest request, ItemImageInfo image, bool cropwhitespace, List <IImageEnhancer> enhancers)
        {
            if (!string.IsNullOrWhiteSpace(request.Format))
            {
                ImageFormat format;
                if (Enum.TryParse(request.Format, true, out format))
                {
                    return(format);
                }
            }

            var         extension   = Path.GetExtension(image.Path);
            ImageFormat?inputFormat = null;

            if (string.Equals(extension, ".jpg", StringComparison.OrdinalIgnoreCase) ||
                string.Equals(extension, ".jpeg", StringComparison.OrdinalIgnoreCase))
            {
                inputFormat = ImageFormat.Jpg;
            }
            else if (string.Equals(extension, ".png", StringComparison.OrdinalIgnoreCase))
            {
                inputFormat = ImageFormat.Png;
            }

            var clientSupportedFormats = GetClientSupportedFormats();

            if (inputFormat.HasValue && clientSupportedFormats.Contains(inputFormat.Value) && enhancers.Count == 0)
            {
                if ((request.Quality ?? 100) == 100 && !request.Height.HasValue && !request.Width.HasValue &&
                    !request.AddPlayedIndicator && !request.PercentPlayed.HasValue && !request.UnplayedCount.HasValue && string.IsNullOrWhiteSpace(request.BackgroundColor))
                {
                    // TODO: Allow this when specfying max width/height if the value is in range
                    if (!cropwhitespace && !request.MaxHeight.HasValue && !request.MaxWidth.HasValue)
                    {
                        return(inputFormat.Value);
                    }
                }
            }

            var serverFormats = _imageProcessor.GetSupportedImageOutputFormats();

            // Client doesn't care about format, so start with webp if supported
            if (serverFormats.Contains(ImageFormat.Webp) && clientSupportedFormats.Contains(ImageFormat.Webp))
            {
                return(ImageFormat.Webp);
            }

            if (enhancers.Count > 0)
            {
                return(ImageFormat.Png);
            }

            if (inputFormat.HasValue && inputFormat.Value == ImageFormat.Jpg)
            {
                return(ImageFormat.Jpg);
            }

            // We can't predict if there will be transparency or not, so play it safe
            return(ImageFormat.Png);
        }
示例#3
0
        private async Task <string> ExtractImage(
            string inputFile,
            string container,
            MediaStream videoStream,
            int?imageStreamIndex,
            MediaSourceInfo mediaSource,
            bool isAudio,
            Video3DFormat?threedFormat,
            TimeSpan?offset,
            ImageFormat?targetFormat,
            CancellationToken cancellationToken)
        {
            var inputArgument = GetInputArgument(inputFile, mediaSource);

            if (!isAudio)
            {
                try
                {
                    return(await ExtractImageInternal(inputArgument, container, videoStream, imageStreamIndex, threedFormat, offset, true, targetFormat, cancellationToken).ConfigureAwait(false));
                }
                catch (ArgumentException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "I-frame image extraction failed, will attempt standard way. Input: {Arguments}", inputArgument);
                }
            }

            return(await ExtractImageInternal(inputArgument, container, videoStream, imageStreamIndex, threedFormat, offset, false, targetFormat, cancellationToken).ConfigureAwait(false));
        }
示例#4
0
        public static string ProcessImage(this IUrlHelper urlHelper, string url, int?width = null, int?height = null, int?quality = null,
                                          ImageMode?mode = null, ImageFormat?format = null)
        {
            string queryString = "?";

            if (width != null)
            {
                queryString += $"width={width}&";
            }
            if (height != null)
            {
                queryString += $"height={height}&";
            }
            if (quality != null)
            {
                queryString += $"quality={quality}&";
            }
            if (mode != null)
            {
                queryString += $"format={format}&";
            }
            if (format != null)
            {
                queryString += $"mode={mode}&";
            }
            queryString = queryString.TrimEnd('?', '&');

            return(url != null?WebPathHelper.CombineUrlParts(url, queryString) : null);
        }
        public static ImageDecoderEnumerator CreateDecoderEnumerator(
            IImagingConfig imagingConfig,
            Stream stream,
            DecoderOptions?decoderOptions       = null,
            CancellationToken cancellationToken = default)
        {
            if (imagingConfig == null)
            {
                throw new ArgumentNullException(nameof(imagingConfig));
            }

            var           prefixStream = imagingConfig.CreateStreamWithHeaderPrefix(stream);
            Memory <byte> prefix       = prefixStream.GetPrefix(cancellationToken);
            ImageFormat?  format       = DetectFormat(imagingConfig, prefix.Span);

            if (format == null)
            {
                if (prefix.Length == 0)
                {
                    throw new UnknownImageFormatException(
                              "No bytes were read from the stream.");
                }
                else
                {
                    throw new UnknownImageFormatException(
                              $"Failed to recognize any format from the first {prefix.Length} bytes.");
                }
            }

            IImageDecoder decoder = imagingConfig.CreateDecoder(prefixStream, format, decoderOptions);

            return(new ImageDecoderEnumerator(decoder, cancellationToken));
        }
示例#6
0
        private async Task <string> ExtractImage(
            string inputFile,
            string container,
            MediaStream videoStream,
            int?imageStreamIndex,
            MediaSourceInfo mediaSource,
            bool isAudio,
            Video3DFormat?threedFormat,
            TimeSpan?offset,
            ImageFormat?targetFormat,
            CancellationToken cancellationToken)
        {
            var inputArgument = GetInputArgument(inputFile, mediaSource);

            if (!isAudio)
            {
                // The failure of HDR extraction usually occurs when using custom ffmpeg that does not contain the zscale filter.
                try
                {
                    return(await ExtractImageInternal(inputArgument, container, videoStream, imageStreamIndex, threedFormat, offset, true, true, targetFormat, cancellationToken).ConfigureAwait(false));
                }
                catch (ArgumentException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "I-frame or HDR image extraction failed, will attempt with I-frame extraction disabled. Input: {Arguments}", inputArgument);
                }

                try
                {
                    return(await ExtractImageInternal(inputArgument, container, videoStream, imageStreamIndex, threedFormat, offset, false, true, targetFormat, cancellationToken).ConfigureAwait(false));
                }
                catch (ArgumentException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "HDR image extraction failed, will fallback to SDR image extraction. Input: {Arguments}", inputArgument);
                }

                try
                {
                    return(await ExtractImageInternal(inputArgument, container, videoStream, imageStreamIndex, threedFormat, offset, true, false, targetFormat, cancellationToken).ConfigureAwait(false));
                }
                catch (ArgumentException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "I-frame image extraction failed, will attempt standard way. Input: {Arguments}", inputArgument);
                }
            }

            return(await ExtractImageInternal(inputArgument, container, videoStream, imageStreamIndex, threedFormat, offset, false, false, targetFormat, cancellationToken).ConfigureAwait(false));
        }
示例#7
0
        public static MemoryStream ToMemoryStream(this Image image, ImageFormat?format = default)
        {
            var stream = new MemoryStream();

            image.Save(stream, format ?? ImageFormat.Bmp);
            stream.Seek(0, SeekOrigin.Begin);

            return(stream);
        }
示例#8
0
        /// <summary>
        /// Get Codec info
        /// 获取编号信息
        /// </summary>
        /// <param name="format">Image format</param>
        /// <returns>Codec info</returns>
        public static ImageCodecInfo?GetCodecInfo(ImageFormat?format)
        {
            if (format == null)
            {
                return(null);
            }

            return(ImageCodecInfo.GetImageEncoders().FirstOrDefault(item => item.FormatID == format.Guid));
        }
示例#9
0
        /// <summary>
        /// Returns a value indicating whether the specified object is an <see cref='ImageFormat'/> equivalent to this
        /// <see cref='ImageFormat'/>.
        /// </summary>
        public override bool Equals(object?o)
        {
            ImageFormat?format = o as ImageFormat;

            if (format == null)
            {
                return(false);
            }
            return(_guid == format._guid);
        }
示例#10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="image"></param>
        /// <param name="format"></param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <returns></returns>
        public static MemoryStream ToMemoryStream(this Image image, ImageFormat?format = default)
        {
            image = image ?? throw new ArgumentNullException(nameof(image));

            var stream = new MemoryStream();

            image.Save(stream, format ?? ImageFormat.Bmp);
            stream.Seek(0, SeekOrigin.Begin);

            return(stream);
        }
示例#11
0
 public static void Save(
     this IEnumerable <IReadOnlyPixelRows> images,
     string filePath,
     ImageFormat?format            = null,
     EncoderOptions?encoderOptions = null,
     ImagingProgressCallback <IImageEncoder>?onProgress = null,
     CancellationToken cancellationToken = default)
 {
     Save(
         images, ImagingConfig.Default, filePath, format,
         encoderOptions, onProgress, cancellationToken);
 }
示例#12
0
        private List <ImageFormat> GetOutputFormats(ImageRequest request, ItemImageInfo image, bool cropwhitespace, List <IImageEnhancer> enhancers)
        {
            if (!string.IsNullOrWhiteSpace(request.Format))
            {
                ImageFormat format;
                if (Enum.TryParse(request.Format, true, out format))
                {
                    return(new List <ImageFormat> {
                        format
                    });
                }
            }

            var         extension   = Path.GetExtension(image.Path);
            ImageFormat?inputFormat = null;

            if (string.Equals(extension, ".jpg", StringComparison.OrdinalIgnoreCase) ||
                string.Equals(extension, ".jpeg", StringComparison.OrdinalIgnoreCase))
            {
                inputFormat = ImageFormat.Jpg;
            }
            else if (string.Equals(extension, ".png", StringComparison.OrdinalIgnoreCase))
            {
                inputFormat = ImageFormat.Png;
            }

            var clientSupportedFormats = GetClientSupportedFormats();

            var serverFormats = _imageProcessor.GetSupportedImageOutputFormats();
            var outputFormats = new List <ImageFormat>();

            // Client doesn't care about format, so start with webp if supported
            if (serverFormats.Contains(ImageFormat.Webp) && clientSupportedFormats.Contains(ImageFormat.Webp))
            {
                outputFormats.Add(ImageFormat.Webp);
            }

            if (enhancers.Count > 0)
            {
                outputFormats.Add(ImageFormat.Png);
            }

            if (inputFormat.HasValue && inputFormat.Value == ImageFormat.Jpg)
            {
                outputFormats.Add(ImageFormat.Jpg);
            }

            // We can't predict if there will be transparency or not, so play it safe
            outputFormats.Add(ImageFormat.Png);

            return(outputFormats);
        }
示例#13
0
 public static byte[] ToArray(this Image image, ImageFormat?format = null)
 {
     format ??= ImageFormat.Png;
     using (MemoryStream ms = new MemoryStream())
     {
         image.Save(ms, format);
         byte[] arr = new byte[ms.Length];
         ms.Position = 0;
         ms.Read(arr, 0, (int)ms.Length);
         ms.Close();
         return(arr);
     }
 }
示例#14
0
        /// <summary>
        /// Save image to stream
        /// 保持图片到流
        /// </summary>
        /// <param name="image">Image</param>
        /// <param name="stream">Stream</param>
        /// <param name="format">Format</param>
        /// <returns>Result</returns>
        public static bool SaveImage(System.Drawing.Image image, Stream stream, ImageFormat?format = null)
        {
            var codec = GetCodecInfo(format ?? image.RawFormat);

            if (codec == null)
            {
                return(false);
            }

            image.Save(stream, codec, GetEncodeParameters());

            return(true);
        }
        /// <summary>
        /// 将图片对象保存为图片文件
        /// </summary>
        /// <param name="image">图片对象</param>
        /// <param name="filePath">要保存的路径,可以是绝对路径或相对路径</param>
        /// <param name="imageFormat">要保存的图片格式,默认为Bmp</param>
        public static void Save(Bitmap image, string filePath, ImageFormat?imageFormat = null)
        {
            string dir = System.IO.Path.GetDirectoryName(filePath) !;

            //如果文件夹不存在,则创建
            if (dir != "" && !Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }

            using System.IO.FileStream fs = new System.IO.FileStream(filePath, System.IO.FileMode.Create, System.IO.FileAccess.Write);
            image.Save(fs, imageFormat ?? ImageFormat.Bmp);
        }
 public Variable(ShaderType type, string name, VariableScope scope, bool @const, uint?asize, bool cr = true, ImageFormat?ifmt = null, uint?si = null, bool flat = false, uint?cidx = null)
 {
     Type          = type;
     Name          = name;
     Scope         = scope;
     Constant      = (Scope == VariableScope.Uniform) || (Scope == VariableScope.Attribute) || (Scope == VariableScope.Constant) || @const;
     ArraySize     = Math.Max(asize.GetValueOrDefault(1), 1);
     IsArray       = asize.HasValue && asize.Value != 0;
     CanRead       = cr;
     ImageFormat   = ifmt;
     SubpassIndex  = si;
     IsFlat        = flat;
     ConstantIndex = cidx;
 }
        public async Task SetCaptureFormat(ImageFormat imageFormat)
        {
            JsonObject imageFormatJson = new JsonObject();

            imageFormatJson.AddValue("Action", "SetCurrentFormat");
            imageFormatJson.AddValue("SubType", imageFormat.Format);
            imageFormatJson.AddValue("Width", imageFormat.Width);
            imageFormatJson.AddValue("Height", imageFormat.Height);
            imageFormatJson.AddValue("BitRate", imageFormat.JsonFormat.GetNamedNumber("Bitrate"));

            await Send(imageFormatJson).ConfigureAwait(false);

            currentImageFormat = imageFormat;
        }
        public static ImageInfo Identify(
            IImagingConfig config, Stream stream, CancellationToken cancellationToken = default)
        {
            using var prefixedStream = config.CreateStreamWithHeaderPrefix(stream);
            Memory <byte> prefix = prefixedStream.GetPrefix(cancellationToken);

            ImageFormat?format = DetectFormat(config, prefix.Span);

            if (format == null)
            {
                throw new UnknownImageFormatException();
            }

            var infoDetector = config.GetInfoDetector(format);

            return(infoDetector.Identify(config, prefixedStream, cancellationToken));
        }
示例#19
0
        public static void Save(
            this IReadOnlyPixelRows image,
            IImagingConfig imagingConfig,
            string filePath,
            ImageFormat?format            = null,
            EncoderOptions?encoderOptions = null,
            ImagingProgressCallback <IImageEncoder>?onProgress = null,
            CancellationToken cancellationToken = default)
        {
            if (format == null)
            {
                format = ImageFormat.GetByPath(filePath)[0];
            }

            Save(
                new[] { image }, imagingConfig, filePath, format,
                encoderOptions, onProgress, cancellationToken);
        }
示例#20
0
 /// <summary>
 /// 图片转化成为 base64
 /// </summary>
 /// <param name="bitmap"></param>
 /// <param name="format"></param>
 /// <returns></returns>
 public static string ToBase64(this Bitmap bitmap, ImageFormat?format = null)
 {
     try
     {
         using (MemoryStream ms = new MemoryStream())
         {
             bitmap.Save(ms, format ?? ImageFormat.Jpeg);
             byte[] arr = new byte[ms.Length];
             ms.Position = 0;
             ms.Read(arr, 0, (int)ms.Length);
             ms.Close();
             return(Convert.ToBase64String(arr));
         }
     }
     catch
     {
         throw;
     }
 }
示例#21
0
        public static void Save(
            this IEnumerable <IReadOnlyPixelRows> images,
            IImagingConfig imagingConfig,
            string filePath,
            ImageFormat?format            = null,
            EncoderOptions?encoderOptions = null,
            ImagingProgressCallback <IImageEncoder>?onProgress = null,
            CancellationToken cancellationToken = default)
        {
            if (format == null)
            {
                format = ImageFormat.GetByPath(filePath)[0];
            }

            using var output = OpenWriteStream(filePath);
            Save(
                images, imagingConfig, output, format,
                encoderOptions, onProgress, cancellationToken);
        }
 // Gets the GLSL keyword that represents the type
 // Image handle types require a format to get the current image type
 internal static string ToGLSLKeyword(this ShaderType type, ImageFormat?ifmt = null)
 {
     if ((type >= TEX_TYPE_START) && (type <= TEX_TYPE_END))
     {
         return(GLSL_KEYWORDS[type - TEX_TYPE_START]);
     }
     else if (type >= IMG_TYPE_START && type <= IMG_TYPE_END)
     {
         if (!ifmt.HasValue)
         {
             return(null);
         }
         var ctype  = ifmt.Value.GetComponentType();
         var prefix = (ctype == ShaderType.Int) ? "i" : (ctype == ShaderType.UInt) ? "u" : "";
         return(prefix + ToSSLKeyword(type));
     }
     else
     {
         return(ToSSLKeyword(type));
     }
 }
        public static ImageFormat?DetectFormat(IImagingConfig config, ReadOnlySpan <byte> header)
        {
            if (config == null)
            {
                throw new ArgumentNullException(nameof(config));
            }

            foreach (IImageFormatDetector formatDetector in config.GetFormatDetectors())
            {
                if (header.Length < formatDetector.HeaderSize)
                {
                    continue;
                }

                ImageFormat?format = formatDetector.DetectFormat(config, header);
                if (format != null)
                {
                    return(format);
                }
            }
            return(null);
        }
示例#24
0
        /// <summary>
        /// Saves the image to the specified file.
        /// </summary>
        /// <param name="filename">The path to the file.</param>
        /// <param name="format">The format to use when saving the image, if not specified the file extension is used to guess the format.</param>
        public void Save(string filename, ImageFormat?format = null)
        {
            ImageFormat actualFormat;

            if (!format.HasValue)
            {
                var extension = Path.GetExtension(filename).ToLowerInvariant();
                if (!imageFomatLookup.TryGetValue(extension, out actualFormat))
                {
                    // couldn't find matching format, perhaps there is no extension or it's not recognised, fallback to default.
                    actualFormat = ImageFormat.Default;
                }
            }
            else
            {
                actualFormat = format.Value;
            }

            if (Interop.LeptonicaApi.Native.pixWrite(filename, handle, actualFormat) != 0)
            {
                throw new IOException(String.Format("Failed to save image '{0}'.", filename));
            }
        }
示例#25
0
 // TODO: maybe refactor this, so the payload gets created somewhere else
 /// <summary> Catch the UploadException! </summary>
 public static async Task <UploadResult> InitiateUpload(Image image, HSSettings settingsContext, Uploader uploader, ImageFormat?format, ITransferProgressReporter?progressReporter)
 {
     format ??= GetImageFormat(image, settingsContext);
     using var payload = new ImageUploadPayload(image, format);
     return(await InitiateUpload(payload, settingsContext, uploader, progressReporter));
 }
示例#26
0
        // TODO: maybe refactor this, so the payload gets created somewhere else
        /// <summary> Catch the UploadException! </summary>
        public static async Task <UploadResult> InitiateUploadToDefaultUploader(Image image, HSSettings settingsContext, UploaderManager uploaderManager, ImageFormat?format, ITransferProgressReporter?progressReporter)
        {
            Debug.Assert(image != null);
            Debug.Assert(settingsContext != null);
            Debug.Assert(uploaderManager != null);

            format ??= GetImageFormat(image, settingsContext);
            using var payload = new ImageUploadPayload(image, format);
            return(await InitiateUploadToDefaultUploader(payload, settingsContext, uploaderManager, progressReporter));
        }
 private Task GetCurrentFormatResponse(JsonObject data)
 {
     currentImageFormat = JsonFormatToImageFormat(data.GetNamedValue("MediaFormat"));
     OnCurrentFormatChanged?.Invoke(this, currentImageFormat.Value);
     return(Task.CompletedTask);
 }
示例#28
0
        private async Task <string> ExtractImageInternal(string inputPath, string container, MediaStream videoStream, int?imageStreamIndex, Video3DFormat?threedFormat, TimeSpan?offset, bool useIFrame, ImageFormat?targetFormat, CancellationToken cancellationToken)
        {
            if (string.IsNullOrEmpty(inputPath))
            {
                throw new ArgumentNullException(nameof(inputPath));
            }

            var outputExtension = targetFormat switch
            {
                ImageFormat.Bmp => ".bmp",
                ImageFormat.Gif => ".gif",
                ImageFormat.Jpg => ".jpg",
                ImageFormat.Png => ".png",
                ImageFormat.Webp => ".webp",
                _ => ".jpg"
            };

            var tempExtractPath = Path.Combine(_configurationManager.ApplicationPaths.TempDirectory, Guid.NewGuid() + outputExtension);

            Directory.CreateDirectory(Path.GetDirectoryName(tempExtractPath));

            // deint -> scale -> thumbnail -> tonemap.
            // put the SW tonemap right after the thumbnail to do it only once to reduce cpu usage.
            var filters = new List <string>();

            // deinterlace using bwdif algorithm for video stream.
            if (videoStream != null && videoStream.IsInterlaced)
            {
                filters.Add("bwdif=0:-1:0");
            }

            // apply some filters to thumbnail extracted below (below) crop any black lines that we made and get the correct ar.
            // This filter chain may have adverse effects on recorded tv thumbnails if ar changes during presentation ex. commercials @ diff ar
            var scaler = threedFormat switch
            {
                // hsbs crop width in half,scale to correct size, set the display aspect,crop out any black bars we may have made. Work out the correct height based on the display aspect it will maintain the aspect where -1 in this case (3d) may not.
                Video3DFormat.HalfSideBySide => "crop=iw/2:ih:0:0,scale=(iw*2):ih,setdar=dar=a,crop=min(iw\\,ih*dar):min(ih\\,iw/dar):(iw-min(iw\\,iw*sar))/2:(ih - min (ih\\,ih/sar))/2,setsar=sar=1",
                // fsbs crop width in half,set the display aspect,crop out any black bars we may have made
                Video3DFormat.FullSideBySide => "crop=iw/2:ih:0:0,setdar=dar=a,crop=min(iw\\,ih*dar):min(ih\\,iw/dar):(iw-min(iw\\,iw*sar))/2:(ih - min (ih\\,ih/sar))/2,setsar=sar=1",
                // htab crop heigh in half,scale to correct size, set the display aspect,crop out any black bars we may have made
                Video3DFormat.HalfTopAndBottom => "crop=iw:ih/2:0:0,scale=(iw*2):ih),setdar=dar=a,crop=min(iw\\,ih*dar):min(ih\\,iw/dar):(iw-min(iw\\,iw*sar))/2:(ih - min (ih\\,ih/sar))/2,setsar=sar=1",
                // ftab crop heigt in half, set the display aspect,crop out any black bars we may have made
                Video3DFormat.FullTopAndBottom => "crop=iw:ih/2:0:0,setdar=dar=a,crop=min(iw\\,ih*dar):min(ih\\,iw/dar):(iw-min(iw\\,iw*sar))/2:(ih - min (ih\\,ih/sar))/2,setsar=sar=1",
                _ => "scale=trunc(iw*sar):ih"
            };

            filters.Add(scaler);

            // Use ffmpeg to sample 100 (we can drop this if required using thumbnail=50 for 50 frames) frames and pick the best thumbnail. Have a fall back just in case.
            // mpegts need larger batch size otherwise the corrupted thumbnail will be created. Larger batch size will lower the processing speed.
            var enableThumbnail = useIFrame && !string.Equals("wtv", container, StringComparison.OrdinalIgnoreCase);

            if (enableThumbnail)
            {
                var useLargerBatchSize = string.Equals("mpegts", container, StringComparison.OrdinalIgnoreCase);
                filters.Add("thumbnail=n=" + (useLargerBatchSize ? "50" : "24"));
            }

            // Use SW tonemap on HDR video stream only when the zscale filter is available.
            var enableHdrExtraction = string.Equals(videoStream?.VideoRange, "HDR", StringComparison.OrdinalIgnoreCase) && SupportsFilter("zscale");

            if (enableHdrExtraction)
            {
                filters.Add("zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=tonemap=hable:desat=0:peak=100,zscale=t=bt709:m=bt709,format=yuv420p");
            }

            var vf     = string.Join(',', filters);
            var mapArg = imageStreamIndex.HasValue ? (" -map 0:" + imageStreamIndex.Value.ToString(CultureInfo.InvariantCulture)) : string.Empty;
            var args   = string.Format(CultureInfo.InvariantCulture, "-i {0}{3} -threads {4} -v quiet -vframes 1 -vf {2} -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg, _threads);

            if (offset.HasValue)
            {
                args = string.Format(CultureInfo.InvariantCulture, "-ss {0} ", GetTimeParameter(offset.Value)) + args;
            }

            if (!string.IsNullOrWhiteSpace(container))
            {
                var inputFormat = EncodingHelper.GetInputFormat(container);
                if (!string.IsNullOrWhiteSpace(inputFormat))
                {
                    args = "-f " + inputFormat + " " + args;
                }
            }

            var process = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    CreateNoWindow  = true,
                    UseShellExecute = false,
                    FileName        = _ffmpegPath,
                    Arguments       = args,
                    WindowStyle     = ProcessWindowStyle.Hidden,
                    ErrorDialog     = false,
                },
                EnableRaisingEvents = true
            };

            _logger.LogDebug("{ProcessFileName} {ProcessArguments}", process.StartInfo.FileName, process.StartInfo.Arguments);

            using (var processWrapper = new ProcessWrapper(process, this))
            {
                bool ranToCompletion;

                await _thumbnailResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);

                try
                {
                    StartProcess(processWrapper);

                    var timeoutMs = _configurationManager.Configuration.ImageExtractionTimeoutMs;
                    if (timeoutMs <= 0)
                    {
                        timeoutMs = enableHdrExtraction ? DefaultHdrImageExtractionTimeout : DefaultSdrImageExtractionTimeout;
                    }

                    ranToCompletion = await process.WaitForExitAsync(TimeSpan.FromMilliseconds(timeoutMs)).ConfigureAwait(false);

                    if (!ranToCompletion)
                    {
                        StopProcess(processWrapper, 1000);
                    }
                }
                finally
                {
                    _thumbnailResourcePool.Release();
                }

                var exitCode = ranToCompletion ? processWrapper.ExitCode ?? 0 : -1;
                var file     = _fileSystem.GetFileInfo(tempExtractPath);

                if (exitCode == -1 || !file.Exists || file.Length == 0)
                {
                    _logger.LogError("ffmpeg image extraction failed for {Path}", inputPath);

                    throw new FfmpegException(string.Format(CultureInfo.InvariantCulture, "ffmpeg image extraction failed for {0}", inputPath));
                }

                return(tempExtractPath);
            }
        }
示例#29
0
        private void ProcessArgv(string[] argv)
        {
            _useStdin  = true;
            _inputFile = _outputFile = null;
            _format    = null;
            _size      = null;
            _quality   = null;
            _threads   = null;

            NoLogo = false;
            Plugin = new string[0];

            var lastarg = argv.Length - 1;

            for (var i = 0; i < argv.Length - 1; i++)
            {
                switch (argv[i])
                {
                case "--help":
                case "-h":
                    Usage(Console.Out);
                    Environment.Exit(0);
                    break;

                case "--nologo":
                    NoLogo = true;
                    break;

                case "--input":
                case "-i":
                    _inputFile = argv.ElementAtOrDefault(i + 1);
                    if (string.IsNullOrWhiteSpace(_inputFile))
                    {
                        Console.Error.WriteLine("Missing parameter for -i/--input.");
                        Usage(Console.Error);
                        Environment.Exit(1);
                    }
                    _useStdin = false;
                    ++i; break;

                case "--format":
                case "-f":
                    if (!Enum.TryParse <ImageFormat>(argv.ElementAtOrDefault(i + 1) ?? "", true, out var fmt))
                    {
                        Console.Error.WriteLine("Invalid format. Supported formats: " + string.Join(", ", Enum.GetValues(typeof(ImageFormat)).OfType <ImageFormat>().Select(x => x.ToString().ToLowerInvariant())));
                        Usage(Console.Error);
                        Environment.Exit(1);
                    }
                    _format = fmt;
                    ++i; break;

                case "--size":
                case "-s":
                    var spl = (argv.ElementAtOrDefault(i + 1) ?? "").Split('x');
                    if (spl.Length != 2 || !spl.All(x => int.TryParse(x, out _)))
                    {
                        Console.Error.WriteLine("Invalid size definition. Please use a lowercase 'x' to separate width and height.");
                        Usage(Console.Error);
                        Environment.Exit(1);
                    }
                    _size = new ImageSize(int.Parse(spl[0]), int.Parse(spl[1]));
                    ++i; break;

                case "--quality":
                case "-q":
                    if (!double.TryParse(argv.ElementAtOrDefault(i + 1) ?? "", NumberStyles.Float, CultureInfo.InvariantCulture, out var q) || q <= 0)
                    {
                        Console.Error.WriteLine("Invalid quality definition. Please use a notation like '1.23' or '10e3' and give a value larger than zero.");
                        Usage(Console.Error);
                        Environment.Exit(1);
                    }
                    _quality = q;
                    ++i; break;

                case "--threads":
                case "-mt":
                    if (!int.TryParse(argv.ElementAtOrDefault(i + 1) ?? "", out var t) || t < 1)
                    {
                        Console.Error.WriteLine("Invalid thread count. Please give a value larger than or equal to 1.");
                        Usage(Console.Error);
                        Environment.Exit(1);
                    }
                    _threads = t;
                    ++i; break;

                case "--plugin":
                    var pglob = argv.ElementAtOrDefault(i + 1);
                    if (string.IsNullOrWhiteSpace(pglob))
                    {
                        Console.Error.WriteLine("Missing parameter for --plugin.");
                        Usage(Console.Error);
                        Environment.Exit(1);
                    }
                    Plugin = Plugin.Concat(new[] { pglob }).ToArray();
                    ++i; break;

                case "--":
                    lastarg = i + 1;
                    break;

                default:
                    Console.Error.WriteLine("Argument not expected: " + argv[i]);
                    Usage(Console.Error);
                    Environment.Exit(1);
                    break;
                }
            }

            _outputFile = argv.ElementAtOrDefault(lastarg);
            if (string.IsNullOrWhiteSpace(_outputFile))
            {
                Console.Error.WriteLine("Please give an output file.");
                Usage(Console.Error);
                Environment.Exit(1);
            }

            if (_format == null)
            {
                var ext = Path.GetExtension(_outputFile).TrimStart('.').ToLowerInvariant();
                if (ext == "jpeg")
                {
                    ext = "jpg";
                }

                if (!Enum.TryParse <ImageFormat>(ext, true, out var fmt))
                {
                    _outputFile += ".bmp";
                    _format      = ImageFormat.Bmp;
                }
                else
                {
                    _format = fmt;
                }
            }
        }
示例#30
0
 public void Save(string outputFile, ImageFormat?format = null)
 {
     //File.WriteAllBytes(outputFile);
     throw new NotImplementedException();
 }