예제 #1
0
        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);
        }
예제 #2
0
        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();
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
            });
        }
예제 #5
0
 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)
     });
 }
예제 #6
0
        /// <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);
            }
        }
예제 #7
0
        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);
            }
        }
예제 #8
0
        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);
        }
예제 #9
0
        /// <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);
        }
예제 #10
0
        /// <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);
        }
예제 #11
0
    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)));
        }
    }