private static float GetYByWatermarkLocation(WatermarkLocation location, int watermarkHeight, int imageHeight) { float y = 0; switch (location) { case WatermarkLocation.TopLeft: case WatermarkLocation.TopCenter: case WatermarkLocation.TopRight: y = 10; break; case WatermarkLocation.MiddleLeft: case WatermarkLocation.MiddleCenter: case WatermarkLocation.MiddleRight: y = (imageHeight - watermarkHeight) / 2.0f; break; case WatermarkLocation.BottomLeft: case WatermarkLocation.BottomCenter: case WatermarkLocation.BottomRight: y = imageHeight - watermarkHeight - 10; break; } return(y); }
static void Main(string[] args) { ImagePath = args[0]; var editableImage = EditableImage.FromFilePath(ImagePath); var watermarkLocation = new WatermarkLocation { Location = Location.BottomLeft, ImageMarginPercentage = 2.5, ImageSizePercentage = 15 }; var watermarkImage = EditableImage.FromFilePath(Path.Combine(Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName), "watermark-disney-white.png")); var watermarkApplier = new WatermarkApplier(watermarkLocation, watermarkImage); watermarkApplier.Apply(editableImage); foreach (var border in _borders) { var borderApplier = new PercentageBorderApplier(border.Value, border.Key); editableImage = borderApplier.Apply(editableImage); } editableImage.Save(); }
private static float GetXByWatermarkLocation(WatermarkLocation location, int watermarkWidth, int imageWidth) { float x = 0; switch (location) { case WatermarkLocation.TopLeft: case WatermarkLocation.MiddleLeft: case WatermarkLocation.BottomLeft: x = 10; break; case WatermarkLocation.TopCenter: case WatermarkLocation.MiddleCenter: case WatermarkLocation.BottomCenter: x = (imageWidth - watermarkWidth) / 2.0f; break; case WatermarkLocation.TopRight: case WatermarkLocation.MiddleRight: case WatermarkLocation.BottomRight: x = imageWidth - watermarkWidth - 10; break; } return(x); }
public void Should_Return_Watermark( bool alignAudio, bool deinterlace, bool intermittent, WatermarkLocation location, bool scaled, int opacity, string expectedVideoFilter, string expectedAudioLabel, string expectedVideoLabel) { var watermark = new ChannelWatermark { Mode = intermittent ? ChannelWatermarkMode.Intermittent : ChannelWatermarkMode.Permanent, DurationSeconds = intermittent ? 15 : 0, FrequencyMinutes = intermittent ? 10 : 0, Location = location, Size = scaled ? WatermarkSize.Scaled : WatermarkSize.ActualSize, WidthPercent = scaled ? 20 : 0, Opacity = opacity, HorizontalMarginPercent = 7, VerticalMarginPercent = 5 }; Option <List <FadePoint> > maybeFadePoints = watermark.Mode == ChannelWatermarkMode.Intermittent ? Some( WatermarkCalculator.CalculateFadePoints( new DateTimeOffset(2022, 01, 31, 12, 25, 0, TimeSpan.FromHours(-5)), TimeSpan.Zero, TimeSpan.FromMinutes(55), TimeSpan.Zero, watermark.FrequencyMinutes, watermark.DurationSeconds)) : None; FFmpegComplexFilterBuilder builder = new FFmpegComplexFilterBuilder() .WithWatermark( Some(watermark), maybeFadePoints, new Resolution { Width = 1920, Height = 1080 }, None) .WithDeinterlace(deinterlace) .WithAlignedAudio(alignAudio ? Some(TimeSpan.FromMinutes(55)) : None); Option <FFmpegComplexFilter> result = builder.Build(false, 0, 0, 0, 1, false); result.IsSome.Should().BeTrue(); result.IfSome( filter => { filter.ComplexFilter.Should().Be(expectedVideoFilter); filter.AudioLabel.Should().Be(expectedAudioLabel); filter.VideoLabel.Should().Be(expectedVideoLabel); }); }
public static PointF GetWatermarkLocationPoint(WatermarkLocation location, System.Drawing.Image watermark, System.Drawing.Image image) { return(new PointF { X = GetXByWatermarkLocation(location, watermark.Width, image.Width), Y = GetYByWatermarkLocation(location, watermark.Height, image.Height) }); }
/// <summary> /// 将指定图片文件加上水印 /// </summary> /// <param name="filename"></param> /// <param name="wType">水印类型</param> /// <param name="wLocation">水印位置</param> /// <param name="Text">水印文字或图片地址。wType为“文字水印”时则为文字内容,否则则为水印图片地址</param> public static void WatermarkImage(String filename, WatermarkType wType, WatermarkLocation wLocation, Font font, Color color, String Text) { String _fileName = HttpContext.Current.Server.MapPath(filename); if (File.Exists(_fileName)) { //创建一个bitmap类型的bmp变量来读取文件。 Bitmap bmp = new Bitmap(_fileName); //新建第二个bitmap类型的bmp2变量,我这里是根据我的程序需要设置的。 Bitmap bmp2 = new Bitmap(bmp.Width, bmp.Height, bmp.PixelFormat); //将第一个bmp拷贝到bmp2中 Graphics draw = Graphics.FromImage(bmp2); draw.DrawImage(bmp, 0, 0); draw.Dispose(); bmp.Dispose();//释放bmp文件资源 bmp2 = GetWatermarkImage(bmp2, wType, wLocation, font, color, Text); bmp2.Save(_fileName); } }
private void ShowMarkEditor(WatermarkLocation location) { var wm = m_config.Marks.Where(a => a.Location == location).FirstOrDefault(); if (wm == null) { wm = new Watermark(); wm.Location = location; } FormWatermarkEditor editor = new FormWatermarkEditor(wm); if (editor.ShowDialog(this) == DialogResult.OK) { var tmp = m_config.Marks.Where(a => a.Location == editor.Mark.Location).FirstOrDefault(); if (tmp != null) { m_config.Marks.Remove(wm); } m_config.Marks.Add(editor.Mark); } }
public static System.Drawing.Image WatermarkImage(this System.Drawing.Image image, System.Drawing.Image watermark, WatermarkLocation location) { using (Graphics imageGraphics = Graphics.FromImage(image)) { var point = GetWatermarkLocationPoint(location, watermark, image); imageGraphics.DrawImage(watermark, point.X, point.Y, watermark.Width, watermark.Height); } return(image); }
/// <summary> /// 生成水印图片 /// </summary> /// <param name="bmp">原图</param> /// <param name="wType">水印类型</param> /// <param name="wLocation">水印位置</param> /// <param name="Text">水印文字或图片地址。wType为“文字水印”时则为文字内容,否则则为水印图片地址</param> /// <returns></returns> protected static Bitmap GetWatermarkImage(Bitmap bmp, WatermarkType wType, WatermarkLocation wLocation, Font font, Color color, String Text) { Bitmap _bmp = bmp; using (Graphics g = Graphics.FromImage(_bmp)) { int w = _bmp.Width; //原图宽度 int h = _bmp.Height; //原图高度 SizeF s = g.MeasureString(Text, font); //文字所占大小 Image img = null; if (wType == WatermarkType.图片水印) { String fileName = HttpContext.Current.Server.MapPath(Text); if (File.Exists(fileName)) { img = Image.FromFile(fileName); if (img.Width > w || img.Height > h) { g.Dispose(); return(_bmp); } s = new SizeF(img.Width, img.Height); } else { g.Dispose(); return(_bmp); } } else { if (s.Width > w || s.Height > h) { return(_bmp); } } Point p = new Point(0, 0); switch (wLocation) { case WatermarkLocation.左: p = new Point(5, 5); break; case WatermarkLocation.中: p = new Point((w - (int)s.Width) / 2, 5); break; case WatermarkLocation.右: p = new Point((w - (int)s.Width) - 5, 5); break; case WatermarkLocation.中左: p = new Point(5, (h - (int)s.Height) / 2); break; case WatermarkLocation.中中: p = new Point((w - (int)s.Width) / 2, (h - (int)s.Height) / 2); break; case WatermarkLocation.中右: p = new Point((w - (int)s.Width) - 5, (h - (int)s.Height) / 2); break; case WatermarkLocation.左: p = new Point(5, (h - (int)s.Height) - 5); break; case WatermarkLocation.中: p = new Point((w - (int)s.Width) / 2, (h - (int)s.Height) - 5); break; case WatermarkLocation.右: p = new Point((w - (int)s.Width) - 5, (h - (int)s.Height) - 5); break; } g.CompositingMode = CompositingMode.SourceOver; g.CompositingQuality = CompositingQuality.HighQuality; if (wType == WatermarkType.图片水印) { float[][] ptsArray = { new float[] { 1, 0, 0, 0, 0 }, new float[] { 0, 1, 0, 0, 0 }, new float[] { 0, 0, 1, 0, 0 }, new float[] { 0, 0, 0, 0.5f, 0 }, //注意:此处为0.5f,图像为半透明 new float[] { 0, 0, 0, 0, 1 } }; ColorMatrix clrMatrix = new ColorMatrix(ptsArray); ImageAttributes imgAttributes = new ImageAttributes(); //设置图像的颜色属性 imgAttributes.SetColorMatrix(clrMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); g.DrawImage(img, new Rectangle(p.X, p.Y, img.Width, img.Height), 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, imgAttributes); img.Dispose(); } else { g.DrawString(Text, font, new SolidBrush(color), p); } } return(_bmp); }
/// <summary> /// Adds a text watermark to an input image filestream /// </summary> /// <param name="fs"></param> /// <param name="watermarkText"></param> /// <param name="outputStream"></param> public static void AddWatermark(FileStream fs, string watermarkText, Color textColor, Font wmFont, WatermarkLocation location, Stream outputStream) { Image img = Image.FromStream(fs); Font font = wmFont; SolidBrush sbrush = new SolidBrush(textColor); Graphics gr = null; try { gr = Graphics.FromImage(img); gr.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height)); //gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; } catch (Exception ex) { Image img1 = img; img = new Bitmap(img1, img.Width, img.Height); gr = Graphics.FromImage(img); gr.DrawImage(img1, new Rectangle(0, 0, img.Width, img.Height));//, 0, 0, img.Width, img.Height, GraphicsUnit.Pixel); img1.Dispose(); } // The position where to draw the watermark on the image SizeF ss = gr.MeasureString(watermarkText, font); // Lower left Point pt = new Point(4, img.Height - ((int)ss.Height + 4)); // Upper left if (location == WatermarkLocation.UpperLeft) { pt = new Point(4, 4); } // Upper right if (location == WatermarkLocation.UpperRight) { pt = new Point(img.Width - ((int)ss.Width + 4), 4); } // Lower right if (location == WatermarkLocation.LowerRight) { pt = new Point(img.Width - ((int)ss.Width + 4), img.Height - ((int)ss.Height + 4)); } // Center if (location == WatermarkLocation.Center) { pt = new Point((img.Width / 2) - (((int)ss.Width / 2)), (img.Height / 2) - (((int)ss.Height / 2))); } // Print gr.DrawString(watermarkText, font, sbrush, pt); // Cleanup gr.Dispose(); // Save to memory stream img.Save(outputStream, ImageFormat.Jpeg); }
public async Task <Either <BaseError, string> > GenerateSongImage( string ffmpegPath, string ffprobePath, Option <string> subtitleFile, Channel channel, Option <ChannelWatermark> playoutItemWatermark, Option <ChannelWatermark> globalWatermark, MediaVersion videoVersion, string videoPath, bool boxBlur, Option <string> watermarkPath, WatermarkLocation watermarkLocation, int horizontalMarginPercent, int verticalMarginPercent, int watermarkWidthPercent, CancellationToken cancellationToken) { try { string outputFile = _tempFilePool.GetNextTempFile(TempFileCategory.SongBackground); MediaStream videoStream = await _ffmpegStreamSelector.SelectVideoStream(videoVersion); Option <ChannelWatermark> watermarkOverride = videoVersion is FallbackMediaVersion or CoverArtMediaVersion ? new ChannelWatermark { Mode = ChannelWatermarkMode.Permanent, HorizontalMarginPercent = horizontalMarginPercent, VerticalMarginPercent = verticalMarginPercent, Location = watermarkLocation, Size = WatermarkSize.Scaled, WidthPercent = watermarkWidthPercent, Opacity = 100 } : None; Option <WatermarkOptions> watermarkOptions = await GetWatermarkOptions( ffprobePath, channel, playoutItemWatermark, globalWatermark, videoVersion, watermarkOverride, watermarkPath); FFmpegPlaybackSettings playbackSettings = _playbackSettingsCalculator.CalculateErrorSettings(channel.FFmpegProfile); FFmpegPlaybackSettings scalePlaybackSettings = _playbackSettingsCalculator.CalculateSettings( StreamingMode.TransportStream, channel.FFmpegProfile, videoVersion, videoStream, None, DateTimeOffset.UnixEpoch, DateTimeOffset.UnixEpoch, TimeSpan.Zero, TimeSpan.Zero, false, Option <int> .None); FFmpegProcessBuilder builder = new FFmpegProcessBuilder(ffmpegPath, false, _logger) .WithThreads(1) .WithQuiet() .WithFormatFlags(playbackSettings.FormatFlags) .WithSongInput(videoPath, videoStream.Codec, videoStream.PixelFormat, boxBlur) .WithWatermark(watermarkOptions, None, channel.FFmpegProfile.Resolution) .WithSubtitleFile(subtitleFile); foreach (IDisplaySize scaledSize in scalePlaybackSettings.ScaledSize) { builder = builder.WithScaling(scaledSize); if (NeedToPad(channel.FFmpegProfile.Resolution, scaledSize)) { builder = builder.WithBlackBars(channel.FFmpegProfile.Resolution); } } using Process process = builder .WithFilterComplex( videoStream, None, videoPath, None, playbackSettings.VideoFormat) .WithOutputFormat("apng", outputFile) .Build(); _logger.LogInformation( "ffmpeg song arguments {FFmpegArguments}", string.Join(" ", process.StartInfo.ArgumentList)); await Cli.Wrap(process.StartInfo.FileName) .WithArguments(process.StartInfo.ArgumentList) .WithValidation(CommandResultValidation.None) .ExecuteAsync(cancellationToken); return(outputFile); } catch (Exception ex) { _logger.LogWarning(ex, "Error generating song image"); _client.Notify(ex); return(Left(BaseError.New(ex.Message))); } }