프로젝트

일반

사용자정보

통계
| 브랜치(Branch): | 개정판:

markus / KCOM / Controls / SignManager.xaml.cs @ 51c6ce90

이력 | 보기 | 이력해설 | 다운로드 (12.3 KB)

1
using KCOM.Common;
2
using Microsoft.Win32;
3
using System;
4
using System.Collections.Generic;
5
using System.IO;
6
using System.Linq;
7
using System.Runtime.Serialization.Formatters.Binary;
8
using System.Text;
9
using System.Threading.Tasks;
10
using System.Windows;
11
using System.Windows.Controls;
12
using System.Windows.Data;
13
using System.Windows.Documents;
14
using System.Windows.Ink;
15
using System.Windows.Input;
16
using System.Windows.Media;
17
using System.Windows.Media.Imaging;
18
using System.Windows.Shapes;
19
using Telerik.Windows.Controls;
20

    
21
namespace KCOM.Controls
22
{
23
    /// <summary>
24
    /// SignManager.xaml에 대한 상호 작용 논리
25
    /// </summary>
26
    public partial class SignManager : UserControl
27
    {
28
        public SignManager()
29
        {
30
            InitializeComponent();
31

    
32
            this.Loaded += SignManager_Loaded;
33
        }
34

    
35
        private void SignManager_Loaded(object sender, RoutedEventArgs e)
36
        {
37
            var signItem = MarkupToPDF.MarkupContext.GetUserSignItem(App.ViewInfo.UserID);  //await ViewerDataModel.Instance.SystemMain.dzMainMenu.BaseTaskClient.GetSignStrokesAsync(App.ViewInfo.ProjectNO, App.ViewInfo.UserID);
38

    
39
            if (signItem != null)
40
            {
41
                StringToStroke(signItem.Strokes);
42
            }
43
        }
44

    
45
        private void Reset_Click(object sender, RoutedEventArgs e)
46
        {
47
            txtInput.Text = "";
48
            txtInput.IsEnabled = true;
49

    
50
            SignCanvas.Strokes.Clear();
51
        }
52

    
53
        private async void Save_Click(object sender, RoutedEventArgs e)
54
        {
55
            if (SignCanvas.Strokes.Count > 0)
56
            {
57
                var signImage = Convert.ToBase64String(SignatureToBitmapBytes());
58

    
59
                var pointes = SignCanvas.Strokes.Select(x => x.GetBounds());
60

    
61
                var _startX = pointes.Min(x => x.X);
62
                var _startY = pointes.Min(x => x.Y);
63

    
64
                var _actualWidth = pointes.Max(x => x.Right);
65
                _actualWidth = Math.Abs(_startX - _actualWidth);
66
                var _actualHeight = pointes.Max(x => x.Bottom);
67
                _actualHeight = Math.Abs(_startY - _actualHeight);
68

    
69
                var result = await ViewerDataModel.Instance.SystemMain.dzMainMenu.BaseTaskClient.SetSignDataAsync(
70
                             App.ViewInfo.UserID, signImage, (int)_startX, (int)_startY, (int)_actualWidth, (int)_actualHeight);
71

    
72
                if (result > 0)
73
                {
74
                    var strokesData = Convert.ToBase64String(StrokesToString());
75

    
76
                    var result2 = await ViewerDataModel.Instance.SystemMain.dzMainMenu.BaseTaskClient.SetSignStrokesAsync(
77
                                 App.ViewInfo.UserID,strokesData);
78

    
79
                    if (result2 > 0)
80
                    {
81
                        MarkupToPDF.MarkupContext.SetUserSignItem(App.ViewInfo.UserID, signImage,strokesData);
82

    
83
                        RadWindow.Alert(new DialogParameters()
84
                        {
85
                            Owner = this,
86
                            Content = "Save Signature Completed."
87
                        });
88

    
89
                    }
90
                    //var signData = await ViewerDataModel.Instance.SystemMain.dzMainMenu.BaseTaskClient.GetSignDataAsync(App.ViewInfo.ProjectNO, App.ViewInfo.UserID);
91

    
92
                    //SetPreview(signData);
93
                }
94
            };
95
        }
96

    
97
        private void SetPreview(string imgStr)
98
        {
99
            byte[] imageBytes = System.Convert.FromBase64String(imgStr);
100

    
101
            BitmapImage returnImage = new BitmapImage();
102

    
103
            using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
104
            {
105
                stream.WriteAsync(imageBytes, 0, imageBytes.Length);
106

    
107
                stream.Position = 0;
108
                System.Drawing.Image img = System.Drawing.Image.FromStream(stream);
109
                returnImage.BeginInit();
110
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
111
                img.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
112
                ms.Seek(0, System.IO.SeekOrigin.Begin);
113
                returnImage.StreamSource = ms;
114
                returnImage.EndInit();
115
                stream.Close();
116
            }
117
        }
118

    
119
        /// <summary>
120
        /// Sign을 비트맵으로 변환하여 리턴한다.
121
        /// </summary>
122
        /// <returns></returns>
123
        private byte[] SignatureToBitmapBytes()
124
        {
125
            RenderTargetBitmap rtb = new RenderTargetBitmap((int)SignCanvas.ActualWidth, (int)SignCanvas.ActualHeight, 96d, 96d, PixelFormats.Default);
126
            rtb.Render(SignCanvas);
127

    
128
            byte[] bytes = null;
129
            using (MemoryStream ms = new MemoryStream())
130
            {
131
                System.Windows.Media.Imaging.PngBitmapEncoder encoder = new PngBitmapEncoder();
132
                BitmapFrame frame = BitmapFrame.Create(rtb);
133
                encoder.Frames.Add(frame);
134
                encoder.Save(ms);
135

    
136
                ms.Position = 0;
137

    
138
                bytes = new byte[ms.Length];
139
                ms.Read(bytes, 0, bytes.Length);
140
            }
141

    
142
            return bytes;
143
        }
144

    
145
        private byte[] StrokesToString()
146
        {
147
            byte[] bytes = null;
148

    
149
            CustomStrokes customStrokes = new CustomStrokes();
150

    
151
            customStrokes.StrokeCollection = new Point[SignCanvas.Strokes.Count][];
152

    
153
            for (int i = 0; i < SignCanvas.Strokes.Count; i++)
154
            {
155
                customStrokes.StrokeCollection[i] = new Point[SignCanvas.Strokes[i].StylusPoints.Count];
156

    
157
                for (int j = 0; j < SignCanvas.Strokes[i].StylusPoints.Count; j++)
158
                {
159
                    customStrokes.StrokeCollection[i][j] = new Point();
160
                    customStrokes.StrokeCollection[i][j].X = SignCanvas.Strokes[i].StylusPoints[j].X;
161
                    customStrokes.StrokeCollection[i][j].Y = SignCanvas.Strokes[i].StylusPoints[j].Y;
162
                }
163
            }
164

    
165
            //Serialize
166
            using (MemoryStream ms = new MemoryStream())
167
            {
168
                BinaryFormatter bf = new BinaryFormatter();
169
                bf.Serialize(ms, customStrokes);
170

    
171
                ms.Position = 0;
172

    
173
                bytes = new byte[ms.Length];
174
                ms.Read(bytes, 0, bytes.Length);
175
            }
176

    
177
            return bytes;
178
        }
179

    
180
        private void StringToStroke(string strokesData)
181
        {
182
            try
183
            {
184
                //deserialize it
185
                BinaryFormatter bf = new BinaryFormatter();
186
                MemoryStream ms = new MemoryStream(Convert.FromBase64String(strokesData));
187

    
188
                CustomStrokes customStrokes = (CustomStrokes)bf.Deserialize(ms);
189

    
190
                //rebuilt it
191
                for (int i = 0; i < customStrokes.StrokeCollection.Length; i++)
192
                {
193
                    if (customStrokes.StrokeCollection[i] != null)
194
                    {
195
                        StylusPointCollection stylusCollection = new StylusPointCollection(customStrokes.StrokeCollection[i]);
196

    
197
                        Stroke stroke = new Stroke(stylusCollection);
198
                        StrokeCollection strokes = new StrokeCollection();
199
                        strokes.Add(stroke);
200

    
201
                        SignCanvas.Strokes.Add(strokes);
202
                    }
203
                }
204
            }
205
            catch (Exception ex)
206
            {
207
            }
208
        }
209

    
210
        public StrokeCollection ConvertImageToStrokeCollection(BitmapImage image)
211
        {  
212
            // 이미지 크기 조정
213
            int maxWidth = 900;
214
            int maxHeight = 200;
215
            double scaleX = (double)maxWidth / image.PixelWidth;
216
            double scaleY = (double)maxHeight / image.PixelHeight;
217
            double scale = Math.Min(scaleX, scaleY);
218

    
219
            TransformedBitmap resizedImage = new TransformedBitmap(image, new ScaleTransform(scale, scale));
220

    
221
            InkCanvas inkCanvas = new InkCanvas();
222
            inkCanvas.Width = resizedImage.Width;
223
            inkCanvas.Height = resizedImage.Height;
224

    
225
            // WriteableBitmap 생성
226
            WriteableBitmap writeableBitmap = new WriteableBitmap(resizedImage);
227

    
228
            // 픽셀 데이터를 저장할 배열 생성
229
            int stride = writeableBitmap.PixelWidth * (writeableBitmap.Format.BitsPerPixel / 8);
230
            byte[] pixelData = new byte[writeableBitmap.PixelHeight * stride];
231

    
232
            // 픽셀 데이터 복사
233
            writeableBitmap.CopyPixels(pixelData, stride, 0);
234

    
235
            progress.Maximum = writeableBitmap.PixelHeight * writeableBitmap.PixelWidth;
236

    
237
            for (int y = 0; y < writeableBitmap.PixelHeight; y++)
238
            {
239
                for (int x = 0; x < writeableBitmap.PixelWidth; x++)
240
                {
241
                    int index = y * stride + x * (writeableBitmap.Format.BitsPerPixel / 8);
242
                    byte blue = pixelData[index];
243
                    byte green = pixelData[index + 1];
244
                    byte red = pixelData[index + 2];
245
                    byte alpha = pixelData[index + 3];
246

    
247
                    Color color = Color.FromArgb(alpha, red, green, blue);
248

    
249
                    // 특정 색상(예: 검정색)인 경우에만 Stroke로 변환
250
                    if (red <= 150 && green <= 150 && blue <= 150 && alpha == 255)
251
                    {
252
                        StylusPointCollection points = new StylusPointCollection();
253
                        points.Add(new StylusPoint(x, y));
254
                        Stroke stroke = new Stroke(points);
255
                        inkCanvas.Strokes.Add(stroke);
256
                    }
257

    
258
                    //System.Threading.Thread.Sleep(10);
259
                    // Update progress value
260
                    //progress.Dispatcher.InvokeAsync(() => { 
261
                    //    progress.Value = y * writeableBitmap.PixelWidth + x + 1;
262
                    //});
263
                }
264
            }
265

    
266
            return inkCanvas.Strokes;
267
        }
268

    
269
        private string GetSignData()
270
        {
271
            string result = "";
272

    
273
            try
274
            {
275

    
276
            }
277
            catch (Exception)
278
            {
279

    
280
                throw;
281
            }
282

    
283
            return result;
284
        }
285

    
286
        private void SignCanvas_SourceUpdated(object sender, DataTransferEventArgs e)
287
        {
288
            if(SignCanvas.Strokes.Count() > 0)
289
            {
290
                txtInput.IsEnabled = false;
291
            }
292
            else
293
            {
294
                txtInput.IsEnabled = true;
295
            }
296
        }
297

    
298
        private void SignCanvas_StrokeCollected(object sender, InkCanvasStrokeCollectedEventArgs e)
299
        {
300
            if (SignCanvas.Strokes.Count() > 0)
301
            {
302
                txtInput.IsEnabled = false;
303
            }
304
            else
305
            {
306
                txtInput.IsEnabled = true;
307
            }
308
        }
309

    
310
        private void OpenImage_Click(object sender, RoutedEventArgs e)
311
        {
312
            OpenFileDialog openFileDialog = new OpenFileDialog();
313
            openFileDialog.Filter = "Image files (*.jpg, *.jpeg, *.png, *.bmp)|*.jpg;*.jpeg;*.png;*.bmp";
314

    
315
            // 파일 선택 대화 상자 표시
316
            if (openFileDialog.ShowDialog() == true)
317
            {
318
                //panelProgress.Dispatcher.InvokeAsync(() => panelProgress.Visibility = Visibility.Visible);
319

    
320
                try
321
                {
322
                    // 선택한 파일 경로 가져오기
323
                    string filePath = openFileDialog.FileName;
324

    
325
                    // BitmapImage 생성 및 파일 로드
326
                    BitmapImage bitmapImage = new BitmapImage();
327
                    bitmapImage.BeginInit();
328
                    bitmapImage.UriSource = new Uri(filePath);
329
                    bitmapImage.EndInit();
330

    
331
                    var strokes = ConvertImageToStrokeCollection(bitmapImage);
332

    
333
                    SignCanvas.Strokes.Add(strokes);
334

    
335
                }
336
                catch (Exception)
337
                {
338
                    MessageBox.Show("이미지 오류입니다.");
339
                }
340
                finally
341
                {
342
                    //panelProgress.Dispatcher.InvokeAsync(() => panelProgress.Visibility = Visibility.Collapsed);
343
                    
344
                }
345
            }
346
        }
347
    }
348

    
349
    [Serializable]
350
    public sealed class CustomStrokes
351
    {
352
        public CustomStrokes() { }
353

    
354
        /// <summary>
355
        /// The first index is the stroke no.
356
        /// The second index is for the keep the 2D point.
357
        /// </summary>
358
        public Point[][] StrokeCollection;
359
    }
360
}
클립보드 이미지 추가 (최대 크기: 500 MB)