프로젝트

일반

사용자정보

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

markus / KCOM / Controls / SignManager.xaml.cs @ 2a824927

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

1 d21e9c15 taeseongkim
using KCOM.Common;
2 a197bf6f taeseongkim
using Microsoft.Win32;
3 d21e9c15 taeseongkim
using System;
4
using System.Collections.Generic;
5 74abcf6f taeseongkim
using System.IO;
6 d21e9c15 taeseongkim
using System.Linq;
7 74abcf6f taeseongkim
using System.Runtime.Serialization.Formatters.Binary;
8 d21e9c15 taeseongkim
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 74abcf6f taeseongkim
using System.Windows.Ink;
15 d21e9c15 taeseongkim
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 74abcf6f taeseongkim
32
            this.Loaded += SignManager_Loaded;
33
        }
34
35 a197bf6f taeseongkim
        private void SignManager_Loaded(object sender, RoutedEventArgs e)
36 74abcf6f taeseongkim
        {
37 a197bf6f taeseongkim
            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 74abcf6f taeseongkim
            {
41 a197bf6f taeseongkim
                StringToStroke(signItem.Strokes);
42 74abcf6f taeseongkim
            }
43 d21e9c15 taeseongkim
        }
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 74abcf6f taeseongkim
            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 b1c2c6fe swate0609
                _actualWidth = Math.Abs(_startX - _actualWidth);
66 74abcf6f taeseongkim
                var _actualHeight = pointes.Max(x => x.Bottom);
67 b1c2c6fe swate0609
                _actualHeight = Math.Abs(_startY - _actualHeight);
68 74abcf6f taeseongkim
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 a197bf6f taeseongkim
                        MarkupToPDF.MarkupContext.SetUserSignItem(App.ViewInfo.UserID, signImage,strokesData);
82
83 74abcf6f taeseongkim
                        RadWindow.Alert(new DialogParameters()
84
                        {
85
                            Content = "Save Signature Completed."
86
                        });
87 a197bf6f taeseongkim
88 74abcf6f taeseongkim
                    }
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 58dd9e89 humkyung
        /// <summary>
119
        /// Sign을 비트맵으로 변환하여 리턴한다.
120
        /// </summary>
121
        /// <returns></returns>
122 74abcf6f taeseongkim
        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 58dd9e89 humkyung
            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 74abcf6f taeseongkim
135 58dd9e89 humkyung
                ms.Position = 0;
136 74abcf6f taeseongkim
137 58dd9e89 humkyung
                bytes = new byte[ms.Length];
138
                ms.Read(bytes, 0, bytes.Length);
139
            }
140 74abcf6f taeseongkim
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 d21e9c15 taeseongkim
        }
208
209 a197bf6f taeseongkim
        public StrokeCollection ConvertImageToStrokeCollection(BitmapImage image)
210 22b925fe taeseongkim
        {  
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 a197bf6f taeseongkim
            InkCanvas inkCanvas = new InkCanvas();
221 22b925fe taeseongkim
            inkCanvas.Width = resizedImage.Width;
222
            inkCanvas.Height = resizedImage.Height;
223 a197bf6f taeseongkim
224
            // WriteableBitmap 생성
225 22b925fe taeseongkim
            WriteableBitmap writeableBitmap = new WriteableBitmap(resizedImage);
226 a197bf6f taeseongkim
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 ce54afaf taeseongkim
            progress.Maximum = writeableBitmap.PixelHeight * writeableBitmap.PixelWidth;
235
236 a197bf6f taeseongkim
            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 ce54afaf taeseongkim
257 cda7efcc taeseongkim
                    System.Threading.Thread.Sleep(10);
258 ce54afaf taeseongkim
                    // Update progress value
259 cda7efcc taeseongkim
                    progress.Dispatcher.InvokeAsync(() => { 
260 ce54afaf taeseongkim
                        progress.Value = y * writeableBitmap.PixelWidth + x + 1;
261
                    });
262 a197bf6f taeseongkim
                }
263
            }
264
265
            return inkCanvas.Strokes;
266
        }
267
268 d21e9c15 taeseongkim
        private string GetSignData()
269
        {
270
            string result = "";
271
272
            try
273
            {
274
275
            }
276
            catch (Exception)
277
            {
278
279
                throw;
280
            }
281
282
            return result;
283
        }
284
285
        private void SignCanvas_SourceUpdated(object sender, DataTransferEventArgs e)
286
        {
287
            if(SignCanvas.Strokes.Count() > 0)
288
            {
289
                txtInput.IsEnabled = false;
290
            }
291
            else
292
            {
293
                txtInput.IsEnabled = true;
294
            }
295
        }
296
297
        private void SignCanvas_StrokeCollected(object sender, InkCanvasStrokeCollectedEventArgs e)
298
        {
299
            if (SignCanvas.Strokes.Count() > 0)
300
            {
301
                txtInput.IsEnabled = false;
302
            }
303
            else
304
            {
305
                txtInput.IsEnabled = true;
306
            }
307
        }
308 a197bf6f taeseongkim
309
        private void OpenImage_Click(object sender, RoutedEventArgs e)
310
        {
311
            OpenFileDialog openFileDialog = new OpenFileDialog();
312
            openFileDialog.Filter = "Image files (*.jpg, *.jpeg, *.png, *.bmp)|*.jpg;*.jpeg;*.png;*.bmp";
313
314
            // 파일 선택 대화 상자 표시
315
            if (openFileDialog.ShowDialog() == true)
316
            {
317 cda7efcc taeseongkim
                panelProgress.Dispatcher.InvokeAsync(() => panelProgress.Visibility = Visibility.Visible);
318 ce54afaf taeseongkim
319
                try
320
                {
321
                    // 선택한 파일 경로 가져오기
322
                    string filePath = openFileDialog.FileName;
323
324
                    // BitmapImage 생성 및 파일 로드
325
                    BitmapImage bitmapImage = new BitmapImage();
326
                    bitmapImage.BeginInit();
327
                    bitmapImage.UriSource = new Uri(filePath);
328
                    bitmapImage.EndInit();
329 a197bf6f taeseongkim
330 ce54afaf taeseongkim
                    var strokes = ConvertImageToStrokeCollection(bitmapImage);
331 a197bf6f taeseongkim
332 ce54afaf taeseongkim
                    SignCanvas.Strokes.Add(strokes);
333 a197bf6f taeseongkim
334 ce54afaf taeseongkim
                }
335
                catch (Exception)
336
                {
337
                    MessageBox.Show("이미지 오류입니다.");
338
                }
339
                finally
340
                {
341 cda7efcc taeseongkim
                    panelProgress.Dispatcher.InvokeAsync(() => panelProgress.Visibility = Visibility.Collapsed);
342
                    
343 ce54afaf taeseongkim
                }
344 a197bf6f taeseongkim
            }
345
        }
346 d21e9c15 taeseongkim
    }
347 74abcf6f taeseongkim
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 d21e9c15 taeseongkim
}
클립보드 이미지 추가 (최대 크기: 500 MB)