209 lines
7.4 KiB
C#
209 lines
7.4 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using System.Windows.Forms;
|
|
using AGVNavigationCore.Models;
|
|
using AGVNavigationCore.Utils;
|
|
|
|
namespace AGVMapEditor.Forms
|
|
{
|
|
/// <summary>
|
|
/// 이미지 노드의 이미지를 편집하기 위한 간단한 그림판
|
|
/// 불러오기, 저장, 크기 조정, 기본 드로잉 기능 제공
|
|
/// </summary>
|
|
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;
|
|
}
|
|
}
|
|
}
|