123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- using SkiaSharp;
- using System;
- using System.IO;
- using Vinno.IUS.Common.Log;
- namespace Vinno.vCloud.Common.Vid2.Codec
- {
- public class VinnoImageEncoder
- {
- private readonly float _xScale;
- private readonly float _yScale;
- private int _currentIndex;
- public VinnoImageEncoder(float xScale = 1.0f, float yScale = 1.0f)
- {
- _currentIndex = -1;
- _xScale = xScale;
- _yScale = yScale;
- }
- /// <summary>
- /// Convert bitmap to jpeg image bytes.
- /// </summary>
- /// <param name="image"></param>
- /// <param name="compressLevel">The compress level for image, default is 75</param>
- /// <returns></returns>
- private byte[] ImageToBytes(SKBitmap image, long compressLevel = 80)
- {
- try
- {
- var newWidth = (int)(image.Width * _xScale);
- var newHeight = (int)(image.Height * _yScale);
- SKBitmap tempImage = image;
- if (image.Width != newWidth || image.Height != newHeight)
- {
- tempImage = image.Resize(new SKImageInfo(newWidth, newHeight), SKFilterQuality.None);
- }
- try
- {
- using (var map = new SKPixmap(new SKImageInfo(tempImage.Width, tempImage.Height, tempImage.ColorType), tempImage.GetPixels()))
- {
- using (var stream = new SKDynamicMemoryWStream())
- {
- SKPixmap.Encode(stream, map, SKEncodedImageFormat.Jpeg, (int)compressLevel);
- return stream.CopyToData().ToArray();
- }
- }
- }
- catch (Exception exception)
- {
- throw new Exception($"ImageToBytes error:{exception}");
- }
- finally
- {
- tempImage.Dispose();
- }
- }
- catch (Exception e)
- {
- Logger.WriteLineError(
- $"Vinno image encode error image width :{image.Width}, image height :{image.Height}, stack is {e}");
- }
- return new byte[0];
- }
- /// <summary>
- /// Encode a bitmap to VinnoImage.
- /// </summary>
- /// <param name="image">The bitmap to be encoded.</param>
- /// <returns>The VinnoImage</returns>
- public VinnoImage Encode(SKBitmap image)
- {
- _currentIndex++;
- return new VinnoImage(_currentIndex, image.Width, image.Height, ImageToBytes(image));
- }
- /// <summary>
- /// Compress a VinnoImage to a 480p image with 50 quality.
- /// </summary>
- /// <param name="vinnoImage"></param>
- /// <returns></returns>
- public VinnoImage Compress(VinnoImage vinnoImage)
- {
- byte[] compressedData = vinnoImage.ImageData;
- using (var ms = new MemoryStream(compressedData))
- {
- using (var image = SKBitmap.Decode(ms))
- {
- //Get 480p ratio
- var ratio = (double)480 / image.Height;
- if (ratio < 1)
- {
- var width = (int)(image.Width * ratio);
- var height = (int)(image.Height * ratio);
- SKBitmap tempImage = image;
- if (image.Width != width || image.Height != height)
- {
- tempImage = image.Resize(new SKImageInfo(width, height), SKFilterQuality.High);
- }
- try
- {
- using (var map = new SKPixmap(new SKImageInfo(tempImage.Width, tempImage.Height, tempImage.ColorType), tempImage.GetPixels()))
- {
- using (var stream = new SKDynamicMemoryWStream())
- {
- SKPixmap.Encode(stream, map, SKEncodedImageFormat.Jpeg, 50);
- compressedData = stream.CopyToData().ToArray();
- }
- }
- }
- catch (Exception exception)
- {
- throw new Exception($"Compress error:{exception}");
- }
- finally
- {
- tempImage.Dispose();
- }
- }
- }
- }
- var updater = new VinnoImageUpdater(vinnoImage);
- updater.Update(compressedData);
- return vinnoImage;
- }
- }
- }
|