diff --git a/Azaion.Annotator/AnnotatorEventHandler.cs b/Azaion.Annotator/AnnotatorEventHandler.cs index ee52a7e..f345f6f 100644 --- a/Azaion.Annotator/AnnotatorEventHandler.cs +++ b/Azaion.Annotator/AnnotatorEventHandler.cs @@ -307,15 +307,8 @@ public class AnnotatorEventHandler( if (!File.Exists(imgPath)) { var source = (mainWindow.Editor.BackgroundImage.Source as BitmapSource)!; - if (source.PixelWidth <= Constants.AI_TILE_SIZE * 2 && source.PixelHeight <= Constants.AI_TILE_SIZE * 2) // Allow to be up to 2560*2560 to save to 1280*1280 - { - //Save image - await using var stream = new FileStream(imgPath, FileMode.Create); - var encoder = new JpegBitmapEncoder(); - encoder.Frames.Add(BitmapFrame.Create(source)); - encoder.Save(stream); - await stream.FlushAsync(cancellationToken); - } + if (new Size(source.PixelWidth, source.PixelHeight).FitSizeForAI()) + await source.SaveImage(imgPath, cancellationToken); else { //Tiling @@ -335,14 +328,9 @@ public class AnnotatorEventHandler( var annotationName = $"{formState.MediaName}{Constants.SPLIT_SUFFIX}{res.Tile.Left:0000}_{res.Tile.Top:0000}!".ToTimeName(time); var tileImgPath = Path.Combine(dirConfig.Value.ImagesDirectory, $"{annotationName}{Constants.JPG_EXT}"); - await using var tileStream = new FileStream(tileImgPath, FileMode.Create); var bitmap = new CroppedBitmap(source, new Int32Rect((int)res.Tile.Left, (int)res.Tile.Top, (int)res.Tile.Width, (int)res.Tile.Height)); - - var tileEncoder = new JpegBitmapEncoder { Frames = [BitmapFrame.Create(bitmap)] }; - tileEncoder.Save(tileStream); - await tileStream.FlushAsync(cancellationToken); - tileStream.Close(); - + await bitmap.SaveImage(tileImgPath, cancellationToken); + var frameSize = new Size(res.Tile.Width, res.Tile.Height); var detections = res.Detections .Select(det => det.ReframeToSmall(res.Tile)) diff --git a/Azaion.Common/Controls/CanvasEditor.cs b/Azaion.Common/Controls/CanvasEditor.cs index 4529f38..2a2f11b 100644 --- a/Azaion.Common/Controls/CanvasEditor.cs +++ b/Azaion.Common/Controls/CanvasEditor.cs @@ -7,6 +7,7 @@ using System.Windows.Media.Imaging; using System.Windows.Shapes; using Azaion.Common.Database; using Azaion.Common.DTO; +using Azaion.Common.Extensions; using MediatR; using Color = System.Windows.Media.Color; using Image = System.Windows.Controls.Image; @@ -473,17 +474,16 @@ public class CanvasEditor : Canvas public void CreateDetections(Annotation annotation, List detectionClasses, Size mediaSize) { - var splitTile = annotation.SplitTile; foreach (var detection in annotation.Detections) { var detectionClass = DetectionClass.FromYoloId(detection.ClassNumber, detectionClasses); CanvasLabel canvasLabel; - if (splitTile == null) + if (!annotation.IsSplit || mediaSize.FitSizeForAI()) canvasLabel = new CanvasLabel(detection, RenderSize, mediaSize, detection.Confidence); else { canvasLabel = new CanvasLabel(detection, new Size(Constants.AI_TILE_SIZE, Constants.AI_TILE_SIZE), null, detection.Confidence) - .ReframeFromSmall(splitTile); + .ReframeFromSmall(annotation.SplitTile!); //From CurrentMediaSize to Render Size var yoloLabel = new YoloLabel(canvasLabel, mediaSize); diff --git a/Azaion.Common/Extensions/BitmapExtensions.cs b/Azaion.Common/Extensions/BitmapExtensions.cs index 294a8bb..de23af7 100644 --- a/Azaion.Common/Extensions/BitmapExtensions.cs +++ b/Azaion.Common/Extensions/BitmapExtensions.cs @@ -26,4 +26,14 @@ public static class BitmapExtensions public static Color CreateTransparent(this Color color, byte transparency) => Color.FromArgb(transparency, color.R, color.G, color.B); + + public static async Task SaveImage(this BitmapSource bitmap, string path, CancellationToken ct = default) + { + await using var stream = new FileStream(path, FileMode.Create); + var encoder = new JpegBitmapEncoder(); + + encoder.Frames.Add(BitmapFrame.Create(bitmap)); + encoder.Save(stream); + await stream.FlushAsync(ct); + } } \ No newline at end of file diff --git a/Azaion.Common/Extensions/SizeExtensions.cs b/Azaion.Common/Extensions/SizeExtensions.cs new file mode 100644 index 0000000..c8e62b4 --- /dev/null +++ b/Azaion.Common/Extensions/SizeExtensions.cs @@ -0,0 +1,10 @@ +using System.Windows; + +namespace Azaion.Common.Extensions; + +public static class SizeExtensions +{ + public static bool FitSizeForAI(this Size size) => + // Allow to be up to FullHD to save as 1280*1280 + size.Width <= Constants.AI_TILE_SIZE * 1.5 && size.Height <= Constants.AI_TILE_SIZE * 1.5; +} \ No newline at end of file diff --git a/Azaion.Dataset/DatasetExplorer.xaml b/Azaion.Dataset/DatasetExplorer.xaml index 2791540..5316645 100644 --- a/Azaion.Dataset/DatasetExplorer.xaml +++ b/Azaion.Dataset/DatasetExplorer.xaml @@ -138,8 +138,9 @@ Header="Редактор" Visibility="Collapsed"> + Background="#01000000" + VerticalAlignment="Stretch" + HorizontalAlignment="Stretch" > diff --git a/Azaion.Dataset/DatasetExplorer.xaml.cs b/Azaion.Dataset/DatasetExplorer.xaml.cs index ed687b5..bf6aabb 100644 --- a/Azaion.Dataset/DatasetExplorer.xaml.cs +++ b/Azaion.Dataset/DatasetExplorer.xaml.cs @@ -195,10 +195,7 @@ public partial class DatasetExplorer ThumbnailsView.SelectedIndex = index; var ann = CurrentAnnotation.Annotation; - ExplorerEditor.Background = new ImageBrush - { - ImageSource = await ann.ImagePath.OpenImage() - }; + ExplorerEditor.SetBackground(await ann.ImagePath.OpenImage()); SwitchTab(toEditor: true); ExplorerEditor.RemoveAllAnns();