public override Image ApplyTransformation(Image image) { // Use original image dimensions if user didn't specify any. if (Width == 0) { Debug.Assert(Height == 0, "If one dimension is zero the other one must be too."); Width = WatermarkImage.Width; Height = WatermarkImage.Height; } if (((Padding * 2) + Width >= image.Width) || ((Padding * 2) + Height >= image.Height)) { // If watermark image + padding is too big we don't make any changes. return(image); } WatermarkImage.Resize(Width, Height, preserveAspectRatio: false, preventEnlarge: false); float alphaScaling = ((float)Opacity) / 100; byte[] watermarkBuffer = WatermarkImage.GetBytes(); Rectangle rect = GetRectangleInsideImage(image, Width, Height); using (Graphics targetGraphics = Graphics.FromImage(image)) { using (MemoryStream memStream = new MemoryStream(watermarkBuffer)) { using (Image watermarkImage = Image.FromStream(memStream)) { AddWatermark(targetGraphics, watermarkImage, rect, alphaScaling); } } } return(image); }
public void Is_Base_Class_Searilzable() { ProjectSetting ps = new ProjectSetting(); WatermarkText wt = new WatermarkText { Text = "Hello world", WatermarkPosition = ContentAlignment.MiddleLeft, WatermarkRotateAngle = 12, WatermarkTextAlignment = StringAlignment.Center }; ps.WatermarkCollection.Add(wt); WatermarkImage wi = new WatermarkImage { WatermarkImageFile = @"c:\temp\1.jpg", WatermarkPosition = ContentAlignment.MiddleCenter }; ps.WatermarkCollection.Add(wi); MemoryStream stream = new MemoryStream(); IFormatter formatter = new BinaryFormatter(); formatter.Serialize(stream, ps); stream.Position = 0; ProjectSetting ps1 = (ProjectSetting)formatter.Deserialize(stream); Assert.AreEqual(ps1.WatermarkCollection.Count, 2); //Assert.IsNull(ps1.WatermarkCollection[2]); //Assert.IsNull(ps1.WatermarkCollection[3]); Assert.IsInstanceOfType(ps1.WatermarkCollection[0], typeof(WatermarkText)); Assert.IsInstanceOfType(ps1.WatermarkCollection[1], typeof(WatermarkImage)); }
private void ProcessImage(object threadIndex) { int index = (int)threadIndex; Trace.WriteLine("Thread " + Thread.CurrentThread.ManagedThreadId + " is created to process indexed item [" + index + "] at " + DateTime.Now + "."); Trace.WriteLine("Current Thread " + Thread.CurrentThread.ManagedThreadId + " Culture " + Thread.CurrentThread.CurrentCulture.ToString() + " during processing."); string imagePath = string.Empty; uint imageIndex = 0; lock (syncRoot) { if (jobQueue.Count > 0) { JobItem item = jobQueue.Dequeue(); imagePath = item.FileName; imageIndex = item.Index; Trace.WriteLine("Thread " + Thread.CurrentThread.ManagedThreadId + " is handling " + imagePath); } else { // nothing more to process, signal #if DEBUG Debug.WriteLine("Thread " + Thread.CurrentThread.ManagedThreadId + " is set because no more image to process at " + DateTime.Now + "."); #endif events[index].Set(); return; } } if (stopFlag) { // stop requested, signal #if DEBUG Debug.WriteLine("Thread " + Thread.CurrentThread.ManagedThreadId + " is set because stop requested."); #endif events[index].Set(); return; } else { ExifMetadata exif = null; Image normalImage = null; Image thumbImage = null; try { if (ps.KeepExif) { // keep exif information from original file exif = new ExifMetadata(new Uri(imagePath), true); Trace.WriteLine("Thread " + Thread.CurrentThread.ManagedThreadId + " obtained EXIF for " + imagePath + " at " + DateTime.Now + "."); } // this will lock image until entire application quits: normalImage = Image.FromFile(imagePath); // following code won't lock image. using (Stream stream = File.OpenRead(imagePath)) { normalImage = Image.FromStream(stream); Trace.WriteLine("Thread " + Thread.CurrentThread.ManagedThreadId + " opened " + imagePath + " at " + DateTime.Now + "."); } ImageFormat format = getImageFormat(imagePath); IProcess process; // thumbnail operation if (ps.ThumbnailSetting.GenerateThumbnail && ps.ThumbnailSetting.ThumbnailSize > 0) { process = container.Resolve <IProcess>("ThumbImage"); thumbImage = process.ProcessImage(normalImage, this.ps); Trace.WriteLine("Thread " + Thread.CurrentThread.ManagedThreadId + " processed thumbnail for " + imagePath + " at " + DateTime.Now + "."); } // shrink image operation if (ps.ShrinkImage && ps.ShrinkPixelTo > 0) { process = container.Resolve <IProcess>("ShrinkImage"); normalImage = process.ProcessImage(normalImage, this.ps); Trace.WriteLine("Thread " + Thread.CurrentThread.ManagedThreadId + " shrinked " + imagePath + " at " + DateTime.Now + "."); } // image process effect if (ps.ProcessType != ImageProcessType.None) { switch (ps.ProcessType) { case ImageProcessType.GrayScale: process = container.Resolve <IProcess>("GrayscaleEffect"); normalImage = process.ProcessImage(normalImage, null); Trace.WriteLine("Thread " + Thread.CurrentThread.ManagedThreadId + " applied GrayscaleEffect for " + imagePath + " at " + DateTime.Now + "."); break; case ImageProcessType.NagativeImage: process = container.Resolve <IProcess>("NegativeEffect"); normalImage = process.ProcessImage(normalImage, null); Trace.WriteLine("Thread " + Thread.CurrentThread.ManagedThreadId + " applied NegativeEffect for " + imagePath + " at " + DateTime.Now + "."); break; case ImageProcessType.OilPaint: process = container.Resolve <IProcess>("OilPaintEffect"); normalImage = process.ProcessImage(normalImage, null); Trace.WriteLine("Thread " + Thread.CurrentThread.ManagedThreadId + " applied OilPaintEffect for " + imagePath + " at " + DateTime.Now + "."); break; case ImageProcessType.PencilSketch: process = container.Resolve <IProcess>("PencilSketchEffect"); normalImage = process.ProcessImage(normalImage, null); Trace.WriteLine("Thread " + Thread.CurrentThread.ManagedThreadId + " applied PencilSketchEffect for " + imagePath + " at " + DateTime.Now + "."); break; case ImageProcessType.Relief: process = container.Resolve <IProcess>("ReliefEffect"); normalImage = process.ProcessImage(normalImage, null); Trace.WriteLine("Thread " + Thread.CurrentThread.ManagedThreadId + " applied ReliefEffect for " + imagePath + " at " + DateTime.Now + "."); break; default: break; } } if (ps.WatermarkCollection != null && ps.WatermarkCollection.Count > 0) { IUnityContainer watermarkContainer; watermarkContainer = container.CreateChildContainer(); watermarkContainer.RegisterInstance <List <ExifContainerItem> >(exifContainer) .RegisterInstance <string>(dateTimeStringFormat); for (int watermarkIndex = 0; watermarkIndex < ps.WatermarkCollection.Count; watermarkIndex++) { watermarkContainer.RegisterInstance <int>(watermarkIndex); if (ps.WatermarkCollection[watermarkIndex] is WatermarkText) { // text watermark operation WatermarkText wt = ps.WatermarkCollection[watermarkIndex] as WatermarkText; if (!string.IsNullOrEmpty(wt.Text) && wt.WatermarkTextColor.A > 0) { #if DEBUG Debug.WriteLine("Current Thread " + Thread.CurrentThread.ManagedThreadId + " Culture " + Thread.CurrentThread.CurrentCulture.ToString() + " before ApplyWatermarkText."); Debug.WriteLine("Current Thread: " + Thread.CurrentThread.ManagedThreadId + ";" + " Image File Name: " + imagePath + "," + " Watermark Text index: " + watermarkIndex + " before."); #endif //process = container.Resolve<IProcess>("WatermarkText"); process = watermarkContainer.Resolve <IProcess>("WatermarkText"); process.ImageFileName = imagePath; normalImage = process.ProcessImage(normalImage, this.ps); } } else if (ps.WatermarkCollection[watermarkIndex] is WatermarkImage) { // image watermark operation WatermarkImage wi = ps.WatermarkCollection[watermarkIndex] as WatermarkImage; if (!string.IsNullOrEmpty(wi.WatermarkImageFile) && File.Exists(wi.WatermarkImageFile) && wi.WatermarkImageOpacity > 0) { #if DEBUG System.Diagnostics.Debug.WriteLine("Current Thread: " + System.Threading.Thread.CurrentThread.ManagedThreadId + ";" + " Image File Name: " + imagePath + "," + " Watermark Image index: " + watermarkIndex + " before."); #endif process = watermarkContainer.Resolve <IProcess>("WatermarkImage"); process.ImageFileName = imagePath; normalImage = process.ProcessImage(normalImage, this.ps); } } } Trace.WriteLine("Thread " + Thread.CurrentThread.ManagedThreadId + " applied watermark(s) for " + imagePath + " at " + DateTime.Now + "."); } // border operation if (ps.BorderSetting.BorderWidth > 0) { process = container.Resolve <IProcess>("AddBorder"); normalImage = process.ProcessImage(normalImage, this.ps); Trace.WriteLine("Thread " + Thread.CurrentThread.ManagedThreadId + " added border for " + imagePath + " at " + DateTime.Now + "."); } // drop shadow operation if (ps.DropShadowSetting.ShadowDepth > 0) { process = container.Resolve <IProcess>("DropShadow"); normalImage = process.ProcessImage(normalImage, this.ps); Trace.WriteLine("Thread " + Thread.CurrentThread.ManagedThreadId + " added dropshadow for " + imagePath + " at " + DateTime.Now + "."); } IFilenameProvider fileNameProvider; if (ps.RenamingSetting.EnableBatchRename) { fileNameProvider = container.Resolve <IFilenameProvider>("BatchRenamedFileName"); } else { fileNameProvider = container.Resolve <IFilenameProvider>("NormalFileName"); } fileNameProvider.PS = ps; fileNameProvider.ImageIndex = imageIndex; fileNameProvider.SourceFileName = imagePath; ISaveImage imageSaver; if (format == ImageFormat.Jpeg) { imageSaver = container.Resolve <ISaveImage>("SaveCompressedJpgImage"); imageSaver.Exif = exif; } else { imageSaver = container.Resolve <ISaveImage>("SaveNormalImage"); } imageSaver.SaveImageToDisk(normalImage, format, fileNameProvider); if (thumbImage != null) { // TODO think about applying thumbImage file name to batch renamed original file fileNameProvider = container.Resolve <IFilenameProvider>("ThumbFileName"); fileNameProvider.PS = ps; fileNameProvider.ImageIndex = imageIndex; fileNameProvider.SourceFileName = imagePath; //saveImage(imagePath, thumbImage, format, fileNameProvider, imageSaver, imageIndex); imageSaver.SaveImageToDisk(thumbImage, format, fileNameProvider); } } catch (Exception ex) { Trace.TraceError(ex.ToString()); } finally { if (normalImage != null) { // if there is an source image in queue which does not exist any more, this could be null. normalImage.Dispose(); normalImage = null; } if (thumbImage != null) { thumbImage.Dispose(); thumbImage = null; } ImageProcessedEventArgs args = new ImageProcessedEventArgs(imagePath); OnImageProcessed(args); } // recursively call itself to go back to check if there are more files waiting to be processed. ProcessImage(threadIndex); } }
public override Image ProcessImage(Image input, ProjectSetting ps) { if (ps.WatermarkCollection.Count < watermarkIndex) { return(input); } WatermarkImage wi = ps.WatermarkCollection[this.watermarkIndex] as WatermarkImage; if (wi == null) { return(input); } #if DEBUG System.Diagnostics.Debug.WriteLine("Current Thread: " + System.Threading.Thread.CurrentThread.ManagedThreadId + "," + " Image File Name: " + this.ImageFileName + "," + " Watermark Image index: " + watermarkIndex); #endif try { // image used as watermark Image watermarkImage; using (Stream stream = File.OpenRead(wi.WatermarkImageFile)) { watermarkImage = Image.FromStream(stream); } Bitmap rotatedWatermarkImage; if (wi.WatermarkRotateAngle > 0 && wi.WatermarkRotateAngle < 360) { rotatedWatermarkImage = RotateImage(watermarkImage, wi.WatermarkRotateAngle); } else { rotatedWatermarkImage = (Bitmap)watermarkImage; } rotatedWatermarkImage = setImageOpacity(rotatedWatermarkImage, (float)wi.WatermarkImageOpacity); //int watermarkWidth = watermarkImage.Width; //int watermarkHeight = watermarkImage.Height; int watermarkWidth = rotatedWatermarkImage.Width; int watermarkHeight = rotatedWatermarkImage.Height; int imageWidth = input.Width; int imageHeight = input.Height; // Create a Bitmap based on the previously modified photograph Bitmap Bitmap bmp = new Bitmap(input); bmp.SetResolution(input.HorizontalResolution, input.VerticalResolution); // Load this Bitmap into a new Graphic Object Graphics graphic = Graphics.FromImage(bmp); int xPosOfWatermark = 0; int yPosOfWatermark = 0; switch (wi.WatermarkPosition) { case ContentAlignment.BottomCenter: xPosOfWatermark = (imageWidth / 2) - (watermarkWidth / 2); yPosOfWatermark = (imageHeight - watermarkHeight) - wi.Padding; break; case ContentAlignment.BottomLeft: xPosOfWatermark = 10; yPosOfWatermark = (imageHeight - watermarkHeight) - wi.Padding; break; case ContentAlignment.BottomRight: xPosOfWatermark = (imageWidth - watermarkWidth) - wi.Padding; yPosOfWatermark = (imageHeight - watermarkHeight) - wi.Padding; break; case ContentAlignment.MiddleCenter: xPosOfWatermark = (imageWidth / 2) - (watermarkWidth / 2); yPosOfWatermark = (imageHeight / 2) - (watermarkHeight / 2); break; case ContentAlignment.MiddleLeft: xPosOfWatermark = wi.Padding; yPosOfWatermark = (imageHeight / 2) - (watermarkHeight / 2); break; case ContentAlignment.MiddleRight: xPosOfWatermark = (imageWidth - watermarkWidth) - wi.Padding; yPosOfWatermark = (imageHeight / 2) - (watermarkHeight / 2); break; case ContentAlignment.TopCenter: xPosOfWatermark = (imageWidth / 2) - (watermarkWidth / 2); yPosOfWatermark = wi.Padding; break; case ContentAlignment.TopLeft: xPosOfWatermark = wi.Padding; yPosOfWatermark = wi.Padding; break; case ContentAlignment.TopRight: //For this example we will place the watermark in the upper right //hand corner of the photograph. offset down 10 pixels and to the //left 10 pixles xPosOfWatermark = (imageWidth - watermarkWidth) - wi.Padding; yPosOfWatermark = wi.Padding; break; } graphic.DrawImage(rotatedWatermarkImage, new Rectangle(xPosOfWatermark, yPosOfWatermark, watermarkWidth, watermarkHeight), //Set the detination Position 0, // x-coordinate of the portion of the source image to draw. 0, // y-coordinate of the portion of the source image to draw. watermarkWidth, // Watermark Width watermarkHeight, // Watermark Height GraphicsUnit.Pixel); // Unit of measurment graphic.Dispose(); return((Image)bmp); } catch (Exception ex) { Trace.TraceError(ex.ToString()); return(input); } }