Добавление прозрачного водяного знака (png) изображения в другое изображение

1

Мне нужно добавить прозрачный водяной знак на большее изображение. Со всем поиском google я дошел до вас. Код, похоже, работает, но изображение воды не помещается правильно и кажется искаженным и теряющим прозрачность. Пожалуйста, дайте мне знать, как я могу исправить эту проблему. Если есть лучший способ достичь этого, пожалуйста, дайте мне знать.

Основное изображение 640x480

Изображение водяного знака 100x86

public static class ImageHelper
{
    #region Public Methods and Operators

    public static Bitmap BitmapSourceToBitmap(BitmapSource bitmapsource)
    {
        Bitmap bitmap;
        using (var outStream = new MemoryStream())
        {
            BitmapEncoder enc = new BmpBitmapEncoder();
            enc.Frames.Add(BitmapFrame.Create(bitmapsource));
            enc.Save(outStream);
            bitmap = new Bitmap(outStream);
        }

        return bitmap;
    }

    public static BitmapSource BitmapToBitmapSource(Bitmap source)
    {
        return Imaging.CreateBitmapSourceFromHBitmap(
            source.GetHbitmap(), 
            IntPtr.Zero, 
            Int32Rect.Empty, 
            BitmapSizeOptions.FromEmptyOptions());
    }

    #endregion

    #region Methods

    public static Image BitmapSourceToImage(BitmapSource image)
    {
        var ms = new MemoryStream();
        var encoder = new BmpBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(image));
        encoder.Save(ms);
        ms.Flush();
        return Image.FromStream(ms);
    }

    public static Bitmap Superimpose(Bitmap largeBmp, Bitmap smallBmp)
    {
        Graphics g = Graphics.FromImage(largeBmp);
        g.CompositingMode = CompositingMode.SourceOver;

        // smallBmp.MakeTransparent();
        int margin = 5;
        int x = largeBmp.Width - smallBmp.Width - margin;
        int y = largeBmp.Height - smallBmp.Height - margin;
        g.DrawImage(smallBmp, new Point(x, y));
        return largeBmp;
    }

    #endregion
}

Код звонка.

        var fs = new FileStream(path, FileMode.Create);

        BitmapSource bitmap = new BitmapImage(new Uri(ImagePath, UriKind.Absolute));
        BitmapSource Logobitmap = new BitmapImage(new Uri(logoPath, UriKind.Absolute));

        bitmap =
            ImageHelper.BitmapToBitmapSource(
                ImageHelper.Superimpose(
                    ImageHelper.BitmapSourceToBitmap(bitmap), 
                    ImageHelper.BitmapSourceToBitmap(Logobitmap)));
        var encoder = new PngBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(bitmap));
        encoder.Save(fs);
        fs.Close();
  • 0
    Убедитесь, что оба растровых изображения имеют одинаковые настройки dpi; лучше всего, установив его!
  • 0
    Рисование с полупрозрачным растровым изображением на непрозрачном растровом изображении приведет к непрозрачному растровому изображению, смешивающему цвета в соответствии с уровнями прозрачности каждого пикселя. Если вы хотите получить полупрозрачный водяной знак, вам нужно изменить пиксели с помощью setpixel. Не такая уж большая проблема для такого маленького изображения водяного знака, если вам не нужно быстро менять много изображений. тогда вы захотите использовать lockbits ..
Теги:
image
watermark

1 ответ

1

Исправлено это для любого, кто нуждается в нем, прочитанного :)

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media.Imaging;

using Point = System.Drawing.Point;

public static class ImageHelper
{
    #region Enums

    public enum ImageType
    {
        Bitmap = 0, 

        PNG = 1
    }

    #endregion

    #region Public Methods and Operators

    public static Bitmap BitmapSourceToBitmap(BitmapSource bitmapsource, ImageType type = ImageType.Bitmap)
    {
        Bitmap bitmap;
        using (var outStream = new MemoryStream())
        {
            BitmapEncoder enc = null;
            if (type == ImageType.Bitmap)
            {
                enc = new BmpBitmapEncoder();
            }
            else
            {
                enc = new PngBitmapEncoder();
            }

            enc.Frames.Add(BitmapFrame.Create(bitmapsource));
            enc.Save(outStream);
            bitmap = new Bitmap(outStream);


        }

        return bitmap;
    }

    public static Image BitmapSourceToImage(BitmapSource image)
    {
        var ms = new MemoryStream();
        var encoder = new BmpBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(image));
        encoder.Save(ms);
        ms.Flush();
        return Image.FromStream(ms);
    }

    public static BitmapSource BitmapToBitmapSource(Bitmap source)
    {
        return Imaging.CreateBitmapSourceFromHBitmap(
            source.GetHbitmap(), 
            IntPtr.Zero, 
            Int32Rect.Empty, 
            BitmapSizeOptions.FromEmptyOptions());
    }

    public static Bitmap SetBitmapResolution(Bitmap bitmap, float dpiX, float dpiY)
    {
        bitmap.SetResolution(dpiX, dpiY);
        return bitmap;
    }

    public static Bitmap Superimpose(Bitmap largeBmp, Bitmap smallBmp)
    {
        Graphics g = Graphics.FromImage(largeBmp);
        g.CompositingMode = CompositingMode.SourceOver;

        // smallBmp.MakeTransparent();
        int margin = 2;
        int x = largeBmp.Width - smallBmp.Width - margin;
        int y = largeBmp.Height - smallBmp.Height - margin;
        g.DrawImage(smallBmp, new Point(x, y));

        return largeBmp;
    }

    #endregion
}

Код звонка

        string logoPath =  "watermark.png";

        var fs = new FileStream(path, FileMode.Create);

        BitmapSource bitmap = [LoadImage]

        if (Settings.Default.AddWaterMark)
        {
            BitmapSource logobitmap = new BitmapImage(new Uri(logoPath, UriKind.Absolute));
            Bitmap mainImgeBitmap = ImageHelper.BitmapSourceToBitmap(bitmap);
            Bitmap logoImageBitmap = ImageHelper.BitmapSourceToBitmap(logobitmap, ImageHelper.ImageType.PNG);
            logoImageBitmap = ImageHelper.SetBitmapResolution(
                logoImageBitmap,
                (float)bitmap.DpiX,
                (float)bitmap.DpiY);
            bitmap = ImageHelper.BitmapToBitmapSource(ImageHelper.Superimpose(mainImgeBitmap, logoImageBitmap));
        }

        var encoder = new PngBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(bitmap));
        encoder.Save(fs);
        fs.Close();

Ещё вопросы

Сообщество Overcoder
Наверх
Меню