Browse Source

ComPDFKit.Tool(Win) - 图章Undo,Redo支持透明度和顺时针逆时针旋转90度还原

liyuxuan 6 months ago
parent
commit
8419fa0c98

+ 5 - 1
Demo/Examples/ComPDFKit.Tool/SettingParam/AnnotParam/StampParam.cs

@@ -18,7 +18,10 @@ namespace ComPDFKit.Tool
 		public C_TEXTSTAMP_COLOR TextStampColor {  get; set; }
 		public MemoryStream ImageStream { get; set; }
 		public int Rotation { get; set; }	
-
+		//暂时做旋转用
+		//后续底层更新旋转角度支持后废除
+		//-1 逆时针 0 未动  1顺时针
+		public int Clockwise {  get; set; }
 
         public override bool CopyTo(AnnotParam transfer)
 		{
@@ -40,6 +43,7 @@ namespace ComPDFKit.Tool
 			stampTransfer.TextStampShape = TextStampShape;
 			stampTransfer.ImageStream = ImageStream;
 			stampTransfer.Rotation = Rotation;
+			stampTransfer.Clockwise = Clockwise;
 
 			return true;
 		}

+ 193 - 6
Demo/Examples/ComPDFKit.Tool/UndoManger/AnnotHistory/StampAnnotHistory.cs

@@ -1,7 +1,11 @@
-using ComPDFKit.PDFAnnotation;
+using ComPDFKit.Import;
+using ComPDFKit.PDFAnnotation;
 using ComPDFKit.PDFPage;
 using ComPDFKit.Tool.Help;
+using System;
 using System.IO;
+using System.IO.Ports;
+using System.Windows;
 using System.Windows.Media;
 using System.Windows.Media.Imaging;
 
@@ -122,9 +126,14 @@ namespace ComPDFKit.Tool.UndoManger
 				}
 
 				stampAnnot.SetTransparency((byte)currentParam.Transparency);
-				
+                string imagePath = string.Empty;
+                if (GetAnnotOpacityImage(stampAnnot, currentParam.Transparency / 255.0, 5, out imagePath) && File.Exists(imagePath))
+                {
+                    stampAnnot.SetImageStamp(imagePath, string.Empty);
+                    File.Delete(imagePath);
+                }
 
-				if (!string.IsNullOrEmpty(currentParam.Author))
+                if (!string.IsNullOrEmpty(currentParam.Author))
 				{
 					stampAnnot.SetAuthor(currentParam.Author);
 				}
@@ -171,10 +180,38 @@ namespace ComPDFKit.Tool.UndoManger
 				StampParam updateParam = (isUndo ? PreviousParam : CurrentParam) as StampParam;
 				StampParam checkParam = (isUndo ? CurrentParam : PreviousParam) as StampParam;
 
-				if (updateParam.Transparency != checkParam.Transparency)
+                if (updateParam.Clockwise!=0)
+                {
+                    string imagePath = string.Empty;
+
+                    bool clockwise = updateParam.Clockwise== 1 ? true : false;
+                    if(isUndo)
+                    {
+                        clockwise=!clockwise;
+                    }
+
+                    if (GetAnnotRotateImage(stampAnnot, clockwise, 5, out imagePath) && File.Exists(imagePath))
+                    {
+                        CRect rawRect = stampAnnot.GetRect();
+                        Point centerPos = new Point(rawRect.left + rawRect.width() / 2, rawRect.top + rawRect.height() / 2);
+                        Rect saveRect = new Rect(centerPos.X - rawRect.height() / 2, centerPos.Y - rawRect.width() / 2, rawRect.height(), rawRect.width());
+
+                        stampAnnot.SetRect(new CRect((float)saveRect.Left, (float)saveRect.Bottom, (float)saveRect.Right, (float)saveRect.Top));
+                        stampAnnot.SetImageStamp(imagePath, string.Empty);
+                        File.Delete(imagePath);
+                    }
+                }
+
+                if (updateParam.Transparency != checkParam.Transparency)
 				{
 					stampAnnot.SetTransparency((byte)updateParam.Transparency);
-				}
+                    string imagePath = string.Empty;
+                    if (GetAnnotOpacityImage(stampAnnot, updateParam.Transparency/255.0, 5, out imagePath) && File.Exists(imagePath))
+                    {
+                        stampAnnot.SetImageStamp(imagePath, string.Empty);
+                        File.Delete(imagePath);
+                    }
+                }
 
 				if (!updateParam.ClientRect.Equals(checkParam.ClientRect))
                 {
@@ -213,5 +250,155 @@ namespace ComPDFKit.Tool.UndoManger
 			}
 			return false;
 		}
-	}
+
+        private bool GetAnnotRotateImage(CPDFStampAnnotation annot, bool clockwise, double zoom, out string imagePath)
+        {
+            imagePath = string.Empty;
+
+            if (annot == null || annot.IsValid() == false)
+            {
+                return false;
+            }
+
+            try
+            {
+                double opacity = annot.GetTransparency() / 255.0;
+                CRect rawRect = annot.GetRect();
+                Rect drawRect = new Rect(0, 0, (int)(rawRect.width() * 96.0 / 72.0 * zoom), (int)(rawRect.height() * 96.0 / 72.0 * zoom));
+
+                byte[] imageData = new byte[(int)drawRect.Width * (int)drawRect.Height * 4];
+                annot.RenderAnnot((int)drawRect.Width, (int)drawRect.Height, imageData);
+
+                int stride = ((int)drawRect.Width) * 4;
+                for (int i = 0; i < (int)(drawRect.Height); i++)
+                {
+                    for (int j = 0; j < (int)(drawRect.Width); j++)
+                    {
+                        byte b = imageData[i * stride + j * 4];
+                        byte g = imageData[i * stride + j * 4 + 1];
+                        byte r = imageData[i * stride + j * 4 + 2];
+                        byte a = imageData[i * stride + j * 4 + 3];
+
+                        if (a == 0 && b == 255 && g == 255 && r == 255)
+                        {
+                            continue;
+                        }
+
+                        if (a == 0 && b == 0 && g == 0 && r == 0)
+                        {
+                            continue;
+                        }
+
+                        imageData[i * stride + j * 4 + 3] = (byte)(opacity * 255);
+                    }
+                }
+
+                WriteableBitmap writeImage = new WriteableBitmap((int)drawRect.Width, (int)drawRect.Height, 96, 96, PixelFormats.Bgra32, null);
+                writeImage.WritePixels(new Int32Rect(0, 0, (int)drawRect.Width, (int)drawRect.Height), imageData, ((int)drawRect.Width) * 4, 0);
+
+                RotateTransform rotateTransform = new RotateTransform();
+                rotateTransform.Angle = clockwise ? 90 : -90;
+                rotateTransform.CenterX = drawRect.Width / 2;
+                rotateTransform.CenterY = drawRect.Height / 2;
+                TranslateTransform translateTransform = new TranslateTransform();
+                if (clockwise == false)
+                {
+                    translateTransform.X = -(drawRect.Width - drawRect.Height) / 2;
+                    translateTransform.Y = -(drawRect.Width - drawRect.Height) / 2;
+                }
+                else
+                {
+                    translateTransform.X = (drawRect.Width - drawRect.Height) / 2;
+                    translateTransform.Y = (drawRect.Width - drawRect.Height) / 2;
+                }
+
+                DrawingVisual drawVisual = new DrawingVisual();
+
+                DrawingContext drawDC = drawVisual.RenderOpen();
+                drawDC.PushTransform(rotateTransform);
+                drawDC.PushTransform(translateTransform);
+                drawDC.DrawImage(writeImage, new Rect(0, 0, writeImage.Width, writeImage.Height));
+                drawDC.Pop();
+                drawDC.Pop();
+                drawDC.Close();
+
+                RenderTargetBitmap renderBitmap = new RenderTargetBitmap((int)drawRect.Height, (int)drawRect.Width, 96, 96, PixelFormats.Pbgra32);
+                renderBitmap.Render(drawVisual);
+                string tempPath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), Guid.NewGuid().ToString());
+                PngBitmapEncoder pngEncoder = new PngBitmapEncoder();
+                using (FileStream fs = File.Create(tempPath))
+                {
+                    pngEncoder.Frames.Add(BitmapFrame.Create(renderBitmap));
+                    pngEncoder.Save(fs);
+                }
+                imagePath = tempPath;
+                return true;
+            }
+            catch (Exception ex)
+            {
+
+            }
+
+            return false;
+        }
+
+        private bool GetAnnotOpacityImage(CPDFStampAnnotation annot, double opacity, double zoom, out string imagePath)
+        {
+            imagePath = string.Empty;
+            if (annot == null || annot.IsValid() == false)
+            {
+                return false;
+            }
+
+            try
+            {
+                CRect rawRect = annot.GetRect();
+                Rect drawRect = new Rect(0, 0, (int)(rawRect.width() * 96.0 / 72.0 * zoom), (int)(rawRect.height() * 96.0 / 72.0 * zoom));
+
+                byte[] imageData = new byte[(int)drawRect.Width * (int)drawRect.Height * 4];
+                annot.RenderAnnot((int)drawRect.Width, (int)drawRect.Height, imageData);
+
+                int stride = ((int)drawRect.Width) * 4;
+                for (int i = 0; i < (int)(drawRect.Height); i++)
+                {
+                    for (int j = 0; j < (int)(drawRect.Width); j++)
+                    {
+                        byte b = imageData[i * stride + j * 4];
+                        byte g = imageData[i * stride + j * 4 + 1];
+                        byte r = imageData[i * stride + j * 4 + 2];
+                        byte a = imageData[i * stride + j * 4 + 3];
+
+                        if (a == 0 && b == 255 && g == 255 && r == 255)
+                        {
+                            continue;
+                        }
+
+                        if (a == 0 && b == 0 && g == 0 && r == 0)
+                        {
+                            continue;
+                        }
+
+                        imageData[i * stride + j * 4 + 3] = (byte)(opacity * 255);
+                    }
+                }
+
+                WriteableBitmap writeImage = new WriteableBitmap((int)drawRect.Width, (int)drawRect.Height, 96, 96, PixelFormats.Bgra32, null);
+                writeImage.WritePixels(new Int32Rect(0, 0, (int)drawRect.Width, (int)drawRect.Height), imageData, stride, 0);
+                string tempPath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), Guid.NewGuid().ToString());
+                PngBitmapEncoder pngEncoder = new PngBitmapEncoder();
+                using (FileStream fs = File.Create(tempPath))
+                {
+                    pngEncoder.Frames.Add(BitmapFrame.Create(writeImage));
+                    pngEncoder.Save(fs);
+                }
+                imagePath = tempPath;
+                return true;
+            }
+            catch (Exception ex)
+            {
+
+            }
+            return false;
+        }
+    }
 }