using System; using System.Drawing; namespace AGVMapEditor.Models { /// /// 맵 이미지 정보를 관리하는 클래스 /// 디자인 요소용 이미지/비트맵 요소 /// public class MapImage { /// /// 이미지 고유 ID /// public string ImageId { get; set; } = string.Empty; /// /// 이미지 파일 경로 /// public string ImagePath { get; set; } = string.Empty; /// /// 맵 상의 위치 좌표 (좌상단 기준) /// public Point Position { get; set; } = Point.Empty; /// /// 이미지 크기 (원본 크기 기준 배율) /// public SizeF Scale { get; set; } = new SizeF(1.0f, 1.0f); /// /// 이미지 투명도 (0.0 ~ 1.0) /// public float Opacity { get; set; } = 1.0f; /// /// 이미지 회전 각도 (도 단위) /// public float Rotation { get; set; } = 0.0f; /// /// 이미지 설명 /// public string Description { get; set; } = string.Empty; /// /// 이미지 생성 일자 /// public DateTime CreatedDate { get; set; } = DateTime.Now; /// /// 이미지 수정 일자 /// public DateTime ModifiedDate { get; set; } = DateTime.Now; /// /// 이미지 활성화 여부 /// public bool IsActive { get; set; } = true; /// /// 로딩된 이미지 (런타임에서만 사용, JSON 직렬화 제외) /// [Newtonsoft.Json.JsonIgnore] public Image LoadedImage { get; set; } /// /// 기본 생성자 /// public MapImage() { } /// /// 매개변수 생성자 /// /// 이미지 ID /// 이미지 파일 경로 /// 위치 public MapImage(string imageId, string imagePath, Point position) { ImageId = imageId; ImagePath = imagePath; Position = position; CreatedDate = DateTime.Now; ModifiedDate = DateTime.Now; } /// /// 이미지 로드 (256x256 이상일 경우 자동 리사이즈) /// /// 로드 성공 여부 public bool LoadImage() { try { if (!string.IsNullOrEmpty(ImagePath) && System.IO.File.Exists(ImagePath)) { LoadedImage?.Dispose(); var originalImage = Image.FromFile(ImagePath); // 이미지 크기 체크 및 리사이즈 if (originalImage.Width > 256 || originalImage.Height > 256) { LoadedImage = ResizeImage(originalImage, 256, 256); originalImage.Dispose(); } else { LoadedImage = originalImage; } return true; } } catch (Exception) { // 이미지 로드 실패 } return false; } /// /// 이미지 리사이즈 (비율 유지) /// /// 원본 이미지 /// 최대 너비 /// 최대 높이 /// 리사이즈된 이미지 private Image 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 resizedImage = new Bitmap(newWidth, newHeight); using (var graphics = Graphics.FromImage(resizedImage)) { graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; graphics.DrawImage(image, 0, 0, newWidth, newHeight); } return resizedImage; } /// /// 실제 표시될 크기 계산 /// /// 실제 크기 public Size GetDisplaySize() { if (LoadedImage == null) return Size.Empty; return new Size( (int)(LoadedImage.Width * Scale.Width), (int)(LoadedImage.Height * Scale.Height) ); } /// /// 문자열 표현 /// public override string ToString() { return $"{ImageId}: {System.IO.Path.GetFileName(ImagePath)} at ({Position.X}, {Position.Y})"; } /// /// 이미지 복사 /// /// 복사된 이미지 public MapImage Clone() { var clone = new MapImage { ImageId = ImageId, ImagePath = ImagePath, Position = Position, Scale = Scale, Opacity = Opacity, Rotation = Rotation, Description = Description, CreatedDate = CreatedDate, ModifiedDate = ModifiedDate, IsActive = IsActive }; // 이미지는 복사하지 않음 (필요시 LoadImage() 호출) return clone; } /// /// 리소스 정리 /// public void Dispose() { LoadedImage?.Dispose(); LoadedImage = null; } } }