프로젝트

일반

사용자정보

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

markus / KCOM / Controls / SignManager.xaml.cs @ ce54afaf

이력 | 보기 | 이력해설 | 다운로드 (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
                            Content = "Save Signature Completed."
86
                        });
87

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

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

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

    
100
            BitmapImage returnImage = new BitmapImage();
101

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

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

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

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

    
135
                ms.Position = 0;
136

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

    
141
            return bytes;
142
        }
143

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

    
148
            CustomStrokes customStrokes = new CustomStrokes();
149

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

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

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

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

    
170
                ms.Position = 0;
171

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

    
176
            return bytes;
177
        }
178

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
256
                        //System.Threading.Thread.SpinWait(10);
257
                    }
258

    
259
                    // Update progress value
260
                    progress.Dispatcher.Invoke(() => { 
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.Invoke(() => 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.Invoke(() => panelProgress.Visibility = Visibility.Collapsed);
343
                }
344
            }
345
        }
346
    }
347

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

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