2014-12-09 2 views
0

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

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

Watermark Image 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

Убедитесь, что оба растровые изображения имеют одинаковые параметры точек на дюйм; лучше, установив его! – TaW

+0

Картина с полупрозрачным растровым изображением на непрозрачном растровом изображении приведет к непрозрачному растровому изображению, смешивая цвета в соответствии с уровнями прозрачности пикселя eacj. Если вы хотите получить полупрозрачный водяной знак, вам нужно будет изменить пиксели с помощью setpixel. Не большая проблема для такого небольшого водяного знака, если вам не нужно быстро менять множество изображений. то вы захотите использовать lockbits. – TaW

ответ

0

Fixed Это для любого, кто нуждается в его читать сделал :)

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();