mirror of https://gitee.com/apiumc/Gateway.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
640 lines
23 KiB
C#
640 lines
23 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.IO.MemoryMappedFiles;
|
|
using System.Linq;
|
|
using SkiaSharp;
|
|
using UMC.Data;
|
|
using UMC.Web;
|
|
using UMC.Net;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
using UMC.Host;
|
|
|
|
namespace UMC.ITME
|
|
{
|
|
class SiteImage
|
|
{
|
|
public string CacheFile
|
|
{
|
|
|
|
get; private set;
|
|
}
|
|
public int Width
|
|
{
|
|
get; private set;
|
|
}
|
|
public int Height
|
|
{
|
|
get; private set;
|
|
}
|
|
public int Postion
|
|
{
|
|
get; private set;
|
|
}
|
|
|
|
SiteImage(int w, int h, int p)
|
|
{
|
|
this.Width = w;
|
|
this.Height = h;
|
|
this.Postion = p;
|
|
}
|
|
string _format;
|
|
void Convert(System.IO.Stream input, System.IO.Stream output)
|
|
{
|
|
try
|
|
{
|
|
using SKCodec sKCodec = SKCodec.Create(input);
|
|
var destImage = SKBitmap.Decode(sKCodec);
|
|
SKCanvas graphics;
|
|
var srcimage = CutForCustom(destImage, out graphics, this.Width, this.Height, this.Postion);
|
|
this.Save(srcimage, sKCodec.EncodedFormat, output);
|
|
srcimage.Dispose();
|
|
destImage.Dispose();
|
|
graphics.Dispose();
|
|
}
|
|
catch //(Exception ex)
|
|
{
|
|
input.CopyTo(output);
|
|
}
|
|
|
|
}
|
|
|
|
public static void Convert(System.IO.Stream input, System.IO.Stream output, Web.WebMeta conf, String cacheFile)
|
|
{
|
|
// System.Net.Quic.QuicConnection
|
|
int width = Utility.IntParse(conf["Width"], 0);
|
|
int height = Utility.IntParse(conf["Height"], 0);
|
|
int Postion = Utility.IntParse(conf["Postion"], 0);
|
|
int ImageSize = Utility.IntParse(conf["ImageSize"], 5);
|
|
int Model = Utility.IntParse(conf["Model"], 0);
|
|
int Padding = Utility.IntParse(conf["Padding"], 10);
|
|
var format = conf["Format"] ?? "Src";
|
|
|
|
switch (conf["WateRmark"] ?? "None")
|
|
{
|
|
case "Text":
|
|
int FontSize = Utility.IntParse(conf["FontSize"], 5);
|
|
SKColor color;//= 0xfff;
|
|
if (SKColor.TryParse(conf["FontColor"] ?? "#8fff", out color) == false)
|
|
{
|
|
color = 0xfff;
|
|
}
|
|
var Font = conf["Font"] ?? "Arial Unicode MS";
|
|
var WateRmarkText = conf["WateRmarkText"];
|
|
if (String.IsNullOrEmpty(WateRmarkText) == false)
|
|
{
|
|
using SKTypeface sKTypeface = SKTypeface.FromFamilyName(Font) ?? SKTypeface.FromFamilyName("Arial Unicode MS");
|
|
new SiteImage(width, height, Model) { _format = format, CacheFile = cacheFile }.WateRmark(input, output, WateRmarkText, FontSize, sKTypeface, color, Postion, Padding);
|
|
|
|
}
|
|
else
|
|
{
|
|
new SiteImage(width, height, Model) { _format = format, CacheFile = cacheFile }.Convert(input, output);
|
|
}
|
|
break;
|
|
case "Image":
|
|
var path = Data.Reflection.ConfigPath($"Static/{conf["ImagePath"]}");
|
|
if (System.IO.File.Exists(path))
|
|
{
|
|
using (var file = File.OpenRead(path))
|
|
{
|
|
new SiteImage(width, height, Model) { _format = format, CacheFile = cacheFile }.WateRmark(input, output, file, ImageSize, Postion, Padding);
|
|
};
|
|
}
|
|
else
|
|
{
|
|
|
|
new SiteImage(width, height, Model) { _format = format, CacheFile = cacheFile }.Convert(input, output);
|
|
}
|
|
break;
|
|
default:
|
|
new SiteImage(width, height, Model) { _format = format, CacheFile = cacheFile }.Convert(input, output);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void WateRmark(System.IO.Stream input, System.IO.Stream output, System.IO.Stream watermark, int size, int postion, int padding)
|
|
{
|
|
try
|
|
{
|
|
using SKCodec sKCodec = SKCodec.Create(input);
|
|
var destImage = SKBitmap.Decode(sKCodec);
|
|
SKCanvas graphics;
|
|
var srcimage = CutForCustom(destImage, out graphics, this.Width, this.Height, this.Postion);
|
|
if (this.Width < 0 && this.Height < 0)
|
|
{
|
|
if ((this.Width * 1000 / this.Height) == (srcimage.Width * 1000 / srcimage.Height))
|
|
{
|
|
var _watermark = SKBitmap.Decode(watermark);
|
|
WateRmark(graphics, srcimage.Width, srcimage.Height, _watermark, size, postion, padding);
|
|
_watermark.Dispose();
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var _watermark = SKBitmap.Decode(watermark);
|
|
WateRmark(graphics, srcimage.Width, srcimage.Height, _watermark, size, postion, padding);
|
|
_watermark.Dispose();
|
|
}
|
|
this.Save(srcimage, sKCodec.EncodedFormat, output);
|
|
destImage.Dispose();
|
|
graphics.Dispose();
|
|
srcimage.Dispose();
|
|
}
|
|
catch//(Exception ex)
|
|
{
|
|
// Utility.Error("App", ex.ToString());
|
|
input.CopyTo(output);
|
|
}
|
|
}
|
|
void Save(SKBitmap bitmap, SKEncodedImageFormat imageFormat, Stream output)
|
|
{
|
|
|
|
switch (_format)
|
|
{
|
|
case "gif":
|
|
bitmap.Encode(output, SKEncodedImageFormat.Gif, 80);
|
|
break;
|
|
case "png":
|
|
bitmap.Encode(output, SKEncodedImageFormat.Png, 80);
|
|
break;
|
|
case "webp":
|
|
bitmap.Encode(output, SKEncodedImageFormat.Webp, 80);
|
|
break;
|
|
case "jpeg":
|
|
bitmap.Encode(output, SKEncodedImageFormat.Jpeg, 80);
|
|
break;
|
|
case "Optimal":
|
|
if (String.IsNullOrEmpty(CacheFile))
|
|
{
|
|
bitmap.Encode(output, SKEncodedImageFormat.Webp, 80);
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
using (var filePng = Utility.Writer($"{CacheFile}.png", false))
|
|
{
|
|
bitmap.Encode(filePng, SKEncodedImageFormat.Png, 80);
|
|
}
|
|
using (var filePng = Utility.Writer($"{CacheFile}.webp", false))
|
|
{
|
|
bitmap.Encode(filePng, SKEncodedImageFormat.Webp, 80);
|
|
}
|
|
|
|
// using (var filePng = Utility.Writer($"{CacheFile}.avif", false))
|
|
// {
|
|
// bitmap.Encode(filePng, SKEncodedImageFormat.Avif, 80);
|
|
// }
|
|
try
|
|
{
|
|
AvifConverter.EncodeImage($"{CacheFile}.png", $"{CacheFile}.avif", new AvifConverterOptions() { Quality = 50 });
|
|
}
|
|
catch
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
break;
|
|
case "avif":
|
|
{
|
|
var tempFile = System.IO.Path.GetTempFileName();
|
|
using (var filePng = Utility.Writer(tempFile, false))
|
|
{
|
|
bitmap.Encode(filePng, SKEncodedImageFormat.Png, 80);
|
|
}
|
|
var tempFile2 = System.IO.Path.GetTempFileName();
|
|
try
|
|
{
|
|
if (AvifConverter.EncodeImage(tempFile, tempFile2, new AvifConverterOptions() { Quality = 50 }).Result.Success)
|
|
{
|
|
using (var fileStream = System.IO.File.OpenRead(tempFile2))
|
|
{
|
|
fileStream.CopyTo(output);
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
if (String.IsNullOrEmpty(CacheFile))
|
|
{
|
|
bitmap.Encode(output, SKEncodedImageFormat.Png, 80);
|
|
|
|
}
|
|
else
|
|
{
|
|
using (var filePng = Utility.Writer($"{CacheFile}.webp", false))
|
|
{
|
|
bitmap.Encode(filePng, SKEncodedImageFormat.Webp, 80);
|
|
}
|
|
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
File.Delete(tempFile);
|
|
File.Delete(tempFile2);
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
case "Src":
|
|
bitmap.Encode(output, imageFormat, 80);
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
void WateRmark(System.IO.Stream input, System.IO.Stream output, String watermarkText, int size, SKTypeface family, SKColor color, int postion, int padding)
|
|
{
|
|
try
|
|
{
|
|
using SKCodec sKCodec = SKCodec.Create(input);
|
|
var destImage = SKBitmap.Decode(sKCodec);
|
|
SKCanvas graphics;
|
|
var srcimage = CutForCustom(destImage, out graphics, this.Width, this.Height, this.Postion);
|
|
if (this.Width < 0 && this.Height < 0)
|
|
{
|
|
if ((this.Width * 1000 / this.Height) == (srcimage.Width * 1000 / srcimage.Height))
|
|
{
|
|
WateRmark(graphics, srcimage.Width, srcimage.Height, watermarkText, size, family, color, postion, padding);
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WateRmark(graphics, srcimage.Width, srcimage.Height, watermarkText, size, family, color, postion, padding);
|
|
}
|
|
//srcimage.Encode(output, _format ?? sKCodec.EncodedFormat, 100);
|
|
|
|
this.Save(srcimage, sKCodec.EncodedFormat, output);
|
|
destImage.Dispose();
|
|
|
|
graphics.Dispose();
|
|
srcimage.Dispose();
|
|
}
|
|
catch
|
|
{
|
|
input.CopyTo(output);
|
|
}
|
|
}
|
|
|
|
static void WateRmark(SKCanvas templateG, int width, int height, SKBitmap watermark, int size, int postion, int padding)
|
|
{
|
|
int w = width * size / 100;
|
|
int h = watermark.Height * w / watermark.Width;
|
|
if (w < 5 || h < 5)
|
|
{
|
|
return;
|
|
}
|
|
int x = 0, y = 0;
|
|
switch (postion % 9)
|
|
{
|
|
case 0:
|
|
x = padding;
|
|
y = padding;
|
|
break;
|
|
case 1:
|
|
y = padding;
|
|
x = (width - w) / 2;
|
|
break;
|
|
case 2:
|
|
x = width - w - padding;
|
|
y = padding;
|
|
break;
|
|
case 3:
|
|
x = padding;
|
|
y = (height - h) / 2;
|
|
break;
|
|
case 4:
|
|
x = (width - w) / 2;
|
|
y = (height - h) / 2;
|
|
break;
|
|
case 5:
|
|
x = (width - w) - padding;
|
|
y = (height - h) / 2;
|
|
break;
|
|
case 6:
|
|
x = padding;
|
|
y = height - h - 10;
|
|
break;
|
|
case 7:
|
|
x = (width - w) / 2;
|
|
y = height - h - 10;
|
|
break;
|
|
case 8:
|
|
x = (width - w) - padding;
|
|
y = height - h - 10;
|
|
break;
|
|
}
|
|
|
|
|
|
|
|
SKRect fromR = SKRect.Create(new SKPoint(0, 0), new SKSize(watermark.Width, watermark.Height));
|
|
SKRect toR = SKRect.Create(new SKPoint(x, y), new SKSize(w, h));
|
|
using (SKPaint paint = new SKPaint())
|
|
{
|
|
paint.Color = paint.Color.WithAlpha(0x88);
|
|
paint.IsAntialias = true;
|
|
using (var wa = watermark.Resize(new SKSizeI(w, h), SKFilterQuality.High))
|
|
{
|
|
templateG.DrawBitmap(wa, toR, paint);
|
|
}
|
|
}
|
|
// templateG.ClipRoundRect()
|
|
// wa.
|
|
|
|
}
|
|
|
|
static void WateRmark(SKCanvas templateG, int width, int height, string watermarkText, int size, SKTypeface family, SKColor color, int postion, int padding)
|
|
{
|
|
int x = 0, y = 0;
|
|
switch (postion % 9)
|
|
{
|
|
case 0:
|
|
x = padding;
|
|
y = padding + size;
|
|
break;
|
|
case 1:
|
|
x = (width - (size * watermarkText.Length)) / 2;
|
|
y = padding + size;
|
|
break;
|
|
case 2:
|
|
x = width - (size * watermarkText.Length) - padding;
|
|
y = padding + size;
|
|
break;
|
|
case 3:
|
|
x = padding;
|
|
y = (height - size) / 2;
|
|
break;
|
|
case 4:
|
|
x = (width - (size * watermarkText.Length)) / 2;
|
|
y = (height - size) / 2;
|
|
break;
|
|
case 5:
|
|
x = (width - (size * watermarkText.Length)) - padding;
|
|
y = (height - size) / 2;
|
|
break;
|
|
case 6:
|
|
x = padding;
|
|
y = height - padding;
|
|
break;
|
|
case 7:
|
|
x = (width - (size * watermarkText.Length)) / 2;
|
|
y = height - padding;
|
|
break;
|
|
case 8:
|
|
x = (width - (size * watermarkText.Length)) - padding;
|
|
y = height - padding;
|
|
break;
|
|
}
|
|
using SKFont font = new SKFont(family, size);
|
|
using SKPaint sKPaint = new SKPaint(font);
|
|
sKPaint.Color = color;
|
|
sKPaint.IsAntialias = true;
|
|
templateG.DrawText(watermarkText, x, y, sKPaint);
|
|
|
|
}
|
|
|
|
static SKBitmap CutForCustom(SKBitmap destImage, out SKCanvas templateG, int confWidth, int confHeight, int postion)
|
|
{
|
|
var maxWidth = confWidth;
|
|
var maxHeight = confHeight;
|
|
// if (confHeight < 0 && confHeight > -10 && confWidth < 0 && confWidth >= -10)
|
|
// {
|
|
// // if(confHeight)
|
|
|
|
// // maxWidth / maxHeight = confWidth / confHeight;
|
|
|
|
// maxWidth = destImage.Height * confWidth / confHeight;
|
|
// maxHeight = destImage.Width * confHeight / confWidth;
|
|
|
|
// }
|
|
// else
|
|
// {
|
|
if (confWidth < 0)
|
|
{
|
|
if (destImage.Width >= Math.Abs(confWidth))
|
|
{
|
|
maxWidth = Math.Abs(confWidth);
|
|
}
|
|
else
|
|
{
|
|
maxWidth = 0;
|
|
}
|
|
}
|
|
|
|
if (confHeight < 0)
|
|
{
|
|
var dheight = destImage.Height;
|
|
if (maxWidth > 0)
|
|
{
|
|
if (destImage.Width > maxWidth)
|
|
{
|
|
dheight = destImage.Height * maxWidth / destImage.Width;
|
|
}
|
|
}
|
|
if (dheight >= Math.Abs(confHeight))
|
|
{
|
|
maxHeight = Math.Abs(confHeight);
|
|
}
|
|
else
|
|
{
|
|
maxHeight = 0;
|
|
}
|
|
}
|
|
// }
|
|
if (maxHeight == 0 && maxWidth == 0)
|
|
{
|
|
templateG = new SKCanvas(destImage);
|
|
return destImage;
|
|
}
|
|
|
|
bool IsThumbnail = false;
|
|
if (maxWidth == 0)
|
|
{
|
|
maxWidth = destImage.Width * maxHeight / destImage.Height;
|
|
IsThumbnail = true;
|
|
}
|
|
else if (maxHeight == 0)
|
|
{
|
|
IsThumbnail = true;
|
|
maxHeight = destImage.Height * maxWidth / destImage.Width;
|
|
}
|
|
|
|
SKSize fromSize = new SKSize();
|
|
SKSize toSize = new SKSize();
|
|
SKPoint formP = new SKPoint();
|
|
SKPoint toP = new SKPoint();
|
|
|
|
if (IsThumbnail)
|
|
{
|
|
if (maxHeight > destImage.Height && maxWidth > destImage.Width)
|
|
{
|
|
templateG = new SKCanvas(destImage);
|
|
return destImage;
|
|
}
|
|
var bmp = destImage.Resize(new SKSizeI(maxWidth, maxHeight), SKFilterQuality.High);
|
|
templateG = new SKCanvas(bmp);
|
|
return bmp;
|
|
}
|
|
if (destImage.Width < maxWidth || destImage.Height < maxHeight)
|
|
{
|
|
|
|
var w = destImage.Width;
|
|
var h = maxHeight * w / maxWidth;
|
|
var h2 = destImage.Height;
|
|
var w2 = maxWidth * h2 / maxHeight;
|
|
if (w > w2)
|
|
{
|
|
maxWidth = w;
|
|
maxHeight = h;
|
|
}
|
|
else
|
|
{
|
|
maxWidth = w2;
|
|
maxHeight = h2;
|
|
}
|
|
}
|
|
if (postion % 4 == 0)
|
|
{
|
|
fromSize.Width = destImage.Width;
|
|
fromSize.Height = destImage.Height;
|
|
var w = fromSize.Width * maxHeight / fromSize.Height;
|
|
|
|
if (w <= maxWidth)
|
|
{
|
|
toP.X = (maxWidth - w) / 2;
|
|
toSize.Height = maxHeight;
|
|
toSize.Width = w;
|
|
}
|
|
else
|
|
{
|
|
var h = fromSize.Height * maxWidth / fromSize.Width;
|
|
toSize.Width = maxWidth;
|
|
toP.Y = (maxHeight - h) / 2;
|
|
toSize.Height = h;
|
|
}
|
|
|
|
if (toSize.Width < fromSize.Width)
|
|
{
|
|
fromSize.Height = toSize.Height;
|
|
fromSize.Width = toSize.Width;
|
|
var bmp = destImage.Resize(new SKSizeI((int)toSize.Width, (int)toSize.Height), SKFilterQuality.High);
|
|
destImage.Dispose();
|
|
destImage = bmp;
|
|
|
|
}
|
|
|
|
var image = new SKBitmap(maxWidth, maxHeight);
|
|
templateG = new SKCanvas(image);
|
|
|
|
templateG.DrawBitmap(destImage, toP.X, toP.Y);
|
|
return image;
|
|
}
|
|
|
|
if (destImage.Width > maxWidth || destImage.Height > maxHeight)
|
|
{
|
|
var w = maxWidth;
|
|
var h = destImage.Height * w / destImage.Width;
|
|
var h2 = maxHeight;
|
|
var w2 = destImage.Width * h2 / destImage.Height;
|
|
if (w > w2)
|
|
{
|
|
var bmp = destImage.Resize(new SKSizeI(w, h), SKFilterQuality.High);
|
|
destImage.Dispose();
|
|
destImage = bmp;
|
|
|
|
}
|
|
else
|
|
{
|
|
var bmp = destImage.Resize(new SKSizeI(w2, h2), SKFilterQuality.High);
|
|
destImage.Dispose();
|
|
destImage = bmp;
|
|
|
|
}
|
|
}
|
|
|
|
switch (postion % 4)
|
|
{
|
|
case 0:
|
|
break;
|
|
case 1:
|
|
{
|
|
toSize.Width = maxWidth;
|
|
toSize.Height = maxHeight;
|
|
var w = maxWidth * destImage.Height / maxHeight;
|
|
if (w > destImage.Width)
|
|
{
|
|
var h = maxHeight * destImage.Width / maxWidth;
|
|
fromSize.Width = destImage.Width;
|
|
fromSize.Height = h;
|
|
}
|
|
else
|
|
{
|
|
fromSize.Width = destImage.Height;
|
|
fromSize.Height = w;
|
|
}
|
|
}
|
|
break;
|
|
case 2:
|
|
{
|
|
toSize.Width = maxWidth;
|
|
toSize.Height = maxHeight;
|
|
var w = maxWidth * destImage.Height / maxHeight;
|
|
if (w > destImage.Width)
|
|
{
|
|
var h = maxHeight * destImage.Width / maxWidth;
|
|
fromSize.Width = destImage.Width;
|
|
fromSize.Height = h;
|
|
formP.Y = (destImage.Height - h) / 2;
|
|
}
|
|
else
|
|
{
|
|
fromSize.Width = w;
|
|
fromSize.Height = destImage.Height;
|
|
formP.X = (destImage.Width - w) / 2;
|
|
}
|
|
}
|
|
break;
|
|
case 3:
|
|
|
|
{
|
|
toSize.Width = maxWidth;
|
|
toSize.Height = maxHeight;
|
|
var w = maxWidth * destImage.Height / maxHeight;
|
|
if (w > destImage.Width)
|
|
{
|
|
var h = maxHeight * destImage.Width / maxWidth;
|
|
fromSize.Width = destImage.Width;
|
|
fromSize.Height = h;
|
|
formP.Y = destImage.Height - h;
|
|
}
|
|
else
|
|
{
|
|
fromSize.Width = w;
|
|
fromSize.Height = destImage.Height;
|
|
|
|
formP.X = destImage.Width - w;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
var templateImage = new SKBitmap(maxWidth, maxHeight);
|
|
templateG = new SKCanvas(templateImage);
|
|
|
|
SKRect fromR = SKRect.Create(formP, fromSize);
|
|
SKRect toR = SKRect.Create(toP, toSize);
|
|
|
|
templateG.DrawBitmap(destImage, fromR, toR);
|
|
return templateImage;
|
|
}
|
|
}
|
|
}
|
|
|