using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; using AGVNavigationCore.Models; using AGVNavigationCore.Utils; namespace AGVMapEditor.Forms { /// /// 이미지 노드의 이미지를 편집하기 위한 간단한 그림판 /// 불러오기, 저장, 크기 조정, 기본 드로잉 기능 제공 /// public partial class ImageEditorForm : Form { private MapImage _targetNode; public ImageEditorForm(MapImage imageNode = null) { InitializeComponent(); _targetNode = imageNode; SetupUI(); if (imageNode != null && imageNode.LoadedImage != null) { LoadImageFromNode(imageNode); } this.KeyPreview = true; this.KeyDown += (s1, e1) => { if (e1.KeyCode == Keys.Escape) this.Close(); }; } private void SetupUI() { // 캔버스 초기 설정 imageCanvas.BrushSize = trackBrush.Value; imageCanvas.BrushModeEnabled = chkBrushMode.Checked; imageCanvas.BackColor = Color.FromArgb(32,32,32); // 이벤트 연결 chkBrushMode.CheckedChanged += (s, e) => imageCanvas.BrushModeEnabled = chkBrushMode.Checked; } private void TrackBrush_ValueChanged(object sender, EventArgs e) { imageCanvas.BrushSize = trackBrush.Value; } private void LoadImageFromNode(MapImage node) { if (node.LoadedImage != null) { imageCanvas.EditingImage = new Bitmap(node.LoadedImage); } } private void BtnOpen_Click(object sender, EventArgs e) { using (var ofd = new OpenFileDialog { Filter = "이미지|*.jpg;*.png;*.bmp|모든 파일|*.*" }) { if (ofd.ShowDialog() == DialogResult.OK) { LoadImageFromFile(ofd.FileName); } } } private void LoadImageFromFile(string filePath) { try { var loadedImage = Image.FromFile(filePath); // 이미지 크기가 크면 자동 축소 (최대 512x512) Bitmap finalImage; if (loadedImage.Width > 512 || loadedImage.Height > 512) { finalImage = ResizeImage(loadedImage, 512, 512); loadedImage.Dispose(); } else { finalImage = new Bitmap(loadedImage); loadedImage.Dispose(); } imageCanvas.EditingImage = finalImage; } catch (Exception ex) { MessageBox.Show($"이미지 로드 실패: {ex.Message}"); } } private void BtnResize_Click(object sender, EventArgs e) { if (imageCanvas.EditingImage == null) { MessageBox.Show("먼저 이미지를 로드하세요."); return; } var currentSize = imageCanvas.ImageDisplaySize; using (var form = new Form()) { form.Text = "이미지 크기 조정"; form.Size = new Size(300, 150); form.StartPosition = FormStartPosition.CenterParent; var lblWidth = new Label { Text = "너비:", Left = 10, Top = 10, Width = 50 }; var txtWidth = new TextBox { Left = 70, Top = 10, Width = 100, Text = currentSize.Width.ToString() }; var lblHeight = new Label { Text = "높이:", Left = 10, Top = 40, Width = 50 }; var txtHeight = new TextBox { Left = 70, Top = 40, Width = 100, Text = currentSize.Height.ToString() }; var btnOk = new Button { Text = "적용", DialogResult = DialogResult.OK, Left = 70, Top = 70, Width = 100 }; var btnCancel = new Button { Text = "취소", DialogResult = DialogResult.Cancel, Left = 180, Top = 70, Width = 70 }; form.Controls.Add(lblWidth); form.Controls.Add(txtWidth); form.Controls.Add(lblHeight); form.Controls.Add(txtHeight); form.Controls.Add(btnOk); form.Controls.Add(btnCancel); if (form.ShowDialog(this) == DialogResult.OK) { if (int.TryParse(txtWidth.Text, out int width) && int.TryParse(txtHeight.Text, out int height)) { if (width > 0 && height > 0) { var resized = new Bitmap(imageCanvas.EditingImage, width, height); imageCanvas.EditingImage = resized; } } } } } private void BtnColor_Click(object sender, EventArgs e) { using (var cfd = new ColorDialog { Color = imageCanvas.DrawColor }) { if (cfd.ShowDialog() == DialogResult.OK) { imageCanvas.DrawColor = cfd.Color; (sender as Button).BackColor = cfd.Color; } } } private void BtnSave_Click(object sender, EventArgs e) { if (imageCanvas.EditingImage == null) { MessageBox.Show("저장할 이미지가 없습니다."); return; } if (_targetNode != null) { // 표시 크기로 리사이즈된 이미지 가져오기 var finalImage = imageCanvas.GetResizedImage(); if (finalImage == null) { MessageBox.Show("이미지 처리 중 오류가 발생했습니다."); return; } var displaySize = imageCanvas.ImageDisplaySize; MessageBox.Show($"이미지 크기: {displaySize.Width}x{displaySize.Height}로 저장됩니다."); // 이미지를 Base64로 변환하여 저장 _targetNode.ImageBase64 = ImageConverterUtil.ImageToBase64(finalImage, System.Drawing.Imaging.ImageFormat.Png); _targetNode.LoadedImage?.Dispose(); _targetNode.LoadedImage = finalImage; MessageBox.Show("이미지가 저장되었습니다."); this.DialogResult = DialogResult.OK; this.Close(); } } private Bitmap ResizeImage(Image image, int maxWidth, int maxHeight) { double ratioX = (double)maxWidth / image.Width; double ratioY = (double)maxHeight / image.Height; double ratio = Math.Min(ratioX, ratioY); int newWidth = (int)(image.Width * ratio); int newHeight = (int)(image.Height * ratio); var resized = new Bitmap(newWidth, newHeight); using (var g = Graphics.FromImage(resized)) { g.CompositingQuality = CompositingQuality.HighQuality; g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.SmoothingMode = SmoothingMode.HighQuality; g.DrawImage(image, 0, 0, newWidth, newHeight); } return resized; } } }