private async void Cancel_Click(object sender, RoutedEventArgs e) { if (CropToolbar != null && CropToolbar.Visibility == Visibility.Visible) { // Reset Cropper await Cropper.SetSourceAsync(_media.File, _media.EditState.Rotation, _media.EditState.Flip, _media.EditState.Proportions, _media.EditState.Rectangle); _rotation = _media.EditState.Rotation; _flip = _media.EditState.Flip; Crop.IsChecked = IsCropped(Cropper.CropRectangle); ResetUiVisibility(); } else if (DrawToolbar != null && DrawToolbar.Visibility == Visibility.Visible) { Canvas.RestoreState(); ResetUiVisibility(); SettingsService.Current.Pencil = DrawSlider.GetDefault(); } else { if (_media is StorageMedia) { _media.EditState = _originalMediaEditState; // Reset to state before starting editing } if (_media is StorageVideo video) { video.IsMuted = _originalVideoIsMuted; video.Compression = _originalVideoCompression; } ResetUiVisibility(); Hide(ContentDialogResult.Secondary); } }
/// <summary> /// Converts the <see cref="PageOrientation"/> to the according <see cref="BitmapRotation"/> value. /// </summary> /// <param name="orientation"><see cref="PageOrientation"/> to convert.</param> /// <param name="cameraType">Camera type.</param> /// <returns>Conversion result.</returns> /// <remarks> /// This method assumes that the preview is horizontally flipped for the front-facing camera. /// </remarks> public static BitmapRotation ConvertOrientationToRotation(PageOrientation orientation, CameraType cameraType) { BitmapRotation rotation = BitmapRotation.None; switch (orientation) { case PageOrientation.Landscape: case PageOrientation.LandscapeLeft: rotation = cameraType == CameraType.Primary ? BitmapRotation.None : BitmapRotation.Clockwise180Degrees; break; case PageOrientation.LandscapeRight: rotation = cameraType == CameraType.Primary ? BitmapRotation.Clockwise180Degrees : BitmapRotation.None; break; case PageOrientation.Portrait: case PageOrientation.PortraitUp: rotation = cameraType == CameraType.Primary ? BitmapRotation.Clockwise90Degrees : BitmapRotation.Clockwise270Degrees; break; case PageOrientation.PortraitDown: rotation = cameraType == CameraType.Primary ? BitmapRotation.Clockwise270Degrees : BitmapRotation.Clockwise90Degrees; break; } return(rotation); }
private async void Rotate_Click(object sender, RoutedEventArgs e) { var rotation = BitmapRotation.None; var proportions = RotateProportions(Cropper.Proportions); var rectangle = RotateArea(Cropper.CropRectangle); switch (_rotation) { case BitmapRotation.None: rotation = BitmapRotation.Clockwise90Degrees; break; case BitmapRotation.Clockwise90Degrees: rotation = BitmapRotation.Clockwise180Degrees; break; case BitmapRotation.Clockwise180Degrees: rotation = BitmapRotation.Clockwise270Degrees; break; } _rotation = rotation; await Cropper.SetSourceAsync(_file, rotation, _flip, proportions, rectangle); Rotate.IsChecked = _rotation != BitmapRotation.None; Canvas.Invalidate(); }
/// <summary> /// Rotates the image at the specified file path. /// </summary> /// <param name="filePath">The file path to the image.</param> /// <param name="rotation">The rotation direction.</param> /// <remarks> /// https://docs.microsoft.com/en-us/uwp/api/windows.graphics.imaging.bitmapdecoder?view=winrt-22000 /// https://docs.microsoft.com/en-us/uwp/api/windows.graphics.imaging.bitmapencoder?view=winrt-22000 /// </remarks> public static async Task Rotate(string filePath, BitmapRotation rotation) { if (string.IsNullOrEmpty(filePath)) { return; } var file = await StorageHelpers.ToStorageItem <IStorageFile>(filePath); if (file == null) { return; } using IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.ReadWrite); BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream); using var memStream = new InMemoryRandomAccessStream(); BitmapEncoder encoder = await BitmapEncoder.CreateForTranscodingAsync(memStream, decoder); encoder.BitmapTransform.Rotation = rotation; await encoder.FlushAsync(); memStream.Seek(0); fileStream.Seek(0); fileStream.Size = 0; await RandomAccessStream.CopyAsync(memStream, fileStream); }
/// <summary> /// Saves and rotates an image. /// </summary> /// <param name="image"> /// The image to rotate. /// </param> /// <param name="rotation"> /// The rotation. /// </param> /// <returns> /// The <see cref="StorageFile"/>. /// </returns> public async Task <StorageFile> SaveAndRotateImage(WriteableBitmap image, BitmapRotation rotation) { var file = await this.SaveCroppedImage(image); var rotated = await this.RotateImage(rotation, file); return(rotated); }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // CONSTRUCTORS / FACTORIES ///////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public ScanResultElement(StorageFile file, int futureAccessListIndex, bool isPartOfDocument) { ScanFile = file; CachedImage = null; ImageWithoutRotation = null; CurrentRotation = BitmapRotation.None; FutureAccessListIndex = futureAccessListIndex; IsPartOfDocument = isPartOfDocument; }
/// <summary> /// Rotates the given stream. /// </summary> /// <param name="randomAccessStream">The random access stream.</param> /// <param name="rotation">The rotation.</param> /// <returns>The stream.</returns> public static async Task <InMemoryRandomAccessStream> Rotate(IRandomAccessStream randomAccessStream, BitmapRotation rotation) { var decoder = await BitmapDecoder.CreateAsync(randomAccessStream); var rotatedStream = new InMemoryRandomAccessStream(); var encoder = await BitmapEncoder.CreateForTranscodingAsync(rotatedStream, decoder); encoder.BitmapTransform.Rotation = rotation; encoder.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Fant; await encoder.FlushAsync(); return(rotatedStream); }
/// <summary> /// Converts a Windows.Graphics.Imaging.BitmapRotation value into a /// Windows.Storage.FileProperties.PhotoOrientation value. /// Note that PhotoOrientation uses a counterclockwise convention, /// while BitmapRotation uses a clockwise convention. /// </summary> public static PhotoOrientation ConvertToPhotoOrientation(BitmapRotation input) { switch (input) { case BitmapRotation.None: return(PhotoOrientation.Normal); case BitmapRotation.Clockwise90Degrees: return(PhotoOrientation.Rotate270); case BitmapRotation.Clockwise180Degrees: return(PhotoOrientation.Rotate180); case BitmapRotation.Clockwise270Degrees: return(PhotoOrientation.Rotate90); default: return(PhotoOrientation.Normal); } }
public async Task SetSourceAsync(StorageFile file, BitmapRotation rotation = BitmapRotation.None) { SoftwareBitmapSource source; using (var fileStream = await ImageHelper.OpenReadAsync(file)) { var decoder = await BitmapDecoder.CreateAsync(fileStream); var transform = ImageHelper.ComputeScalingTransformForSourceImage(decoder); transform.Rotation = rotation; var software = await decoder.GetSoftwareBitmapAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied, transform, ExifOrientationMode.RespectExifOrientation, ColorManagementMode.DoNotColorManage); source = new SoftwareBitmapSource(); await source.SetBitmapAsync(software); SetSource(file, source, software.PixelWidth, software.PixelHeight); } Canvas.SetLeft(m_imageThumb, (m_layoutRoot.ActualWidth - m_imageSize.Width) / 2.0); Canvas.SetTop(m_imageThumb, (m_layoutRoot.ActualHeight - m_imageSize.Height) / 2.0); var imageScale = m_imageSize.Width / m_imageSize.Height; var cropScale = GetProportionsFactor(Proportions, imageScale); if (imageScale < cropScale) { var cropHeight = m_imageSize.Width / cropScale; m_cropRectangle = new Rect(0.0, (m_imageSize.Height - cropHeight) / 2.0, m_imageSize.Width, cropHeight); } else { var cropWidth = m_imageSize.Height * cropScale; m_cropRectangle = new Rect((m_imageSize.Width - cropWidth) / 2.0, 0.0, cropWidth, m_imageSize.Height); } UpdateCropRectangle(m_cropRectangle, false); }
private async Task <StorageFile> RotateImage(BitmapRotation rotation, IStorageFile file) { int wbRotate = 0; switch (rotation) { case BitmapRotation.Clockwise90Degrees: wbRotate = 90; break; case BitmapRotation.Clockwise180Degrees: wbRotate = 180; break; case BitmapRotation.Clockwise270Degrees: wbRotate = 270; break; } var result = await this.RotateImage(wbRotate, file); return(result); }
/// <summary> /// Converts a Windows.Graphics.Imaging.BitmapRotation value into a /// Windows.Storage.FileProperties.PhotoOrientation value. /// Note that PhotoOrientation uses a counterclockwise convention, /// while BitmapRotation uses a clockwise convention. /// </summary> public static PhotoOrientation ConvertToPhotoOrientation(BitmapRotation input) { switch (input) { case BitmapRotation.None: return PhotoOrientation.Normal; case BitmapRotation.Clockwise90Degrees: return PhotoOrientation.Rotate270; case BitmapRotation.Clockwise180Degrees: return PhotoOrientation.Rotate180; case BitmapRotation.Clockwise270Degrees: return PhotoOrientation.Rotate90; default: return PhotoOrientation.Normal; } }
public static async Task <StorageFile> DrawStrokesAsync(StorageFile file, IReadOnlyList <SmoothPathBuilder> strokes, Rect rectangle, BitmapRotation rotation, BitmapFlip flip) { var device = CanvasDevice.GetSharedDevice(); var bitmap = await CanvasBitmap.LoadAsync(device, file.Path); var canvas1 = new CanvasRenderTarget(device, (float)bitmap.Size.Width, (float)bitmap.Size.Height, bitmap.Dpi); var canvas2 = new CanvasRenderTarget(device, (float)bitmap.Size.Width, (float)bitmap.Size.Height, bitmap.Dpi); var size = canvas1.Size.ToVector2(); var canvasSize = canvas1.Size.ToVector2(); var scaleX = 1 / (float)rectangle.Width; var scaleY = 1 / (float)rectangle.Height; var offsetX = (float)rectangle.X * scaleX; var offsetY = (float)rectangle.Y * scaleY; if (rotation is BitmapRotation.Clockwise270Degrees or BitmapRotation.Clockwise90Degrees) { size = new Vector2(size.Y, size.X); scaleX = scaleY; scaleY = 1 * 1 / (float)rectangle.Width; } using (var session = canvas1.CreateDrawingSession()) { switch (rotation) { case BitmapRotation.Clockwise90Degrees: var transform1 = Matrix3x2.CreateRotation(MathFEx.ToRadians(90)); transform1.Translation = new Vector2(size.Y, 0); session.Transform = transform1; break; case BitmapRotation.Clockwise180Degrees: var transform2 = Matrix3x2.CreateRotation(MathFEx.ToRadians(180)); transform2.Translation = new Vector2(size.X, size.Y); session.Transform = transform2; break; case BitmapRotation.Clockwise270Degrees: var transform3 = Matrix3x2.CreateRotation(MathFEx.ToRadians(270)); transform3.Translation = new Vector2(0, size.X); session.Transform = transform3; break; } switch (flip) { case BitmapFlip.Horizontal: switch (rotation) { case BitmapRotation.Clockwise90Degrees: case BitmapRotation.Clockwise270Degrees: session.Transform = Matrix3x2.Multiply(session.Transform, Matrix3x2.CreateScale(1, -1, canvasSize / 2)); break; default: session.Transform = Matrix3x2.Multiply(session.Transform, Matrix3x2.CreateScale(-1, 1, canvasSize / 2)); break; } break; case BitmapFlip.Vertical: switch (rotation) { case BitmapRotation.None: case BitmapRotation.Clockwise180Degrees: session.Transform = Matrix3x2.Multiply(session.Transform, Matrix3x2.CreateScale(1, -1, canvasSize / 2)); break; default: session.Transform = Matrix3x2.Multiply(session.Transform, Matrix3x2.CreateScale(-1, 1, canvasSize / 2)); break; } break; } session.Transform = Matrix3x2.Multiply(session.Transform, Matrix3x2.CreateScale(scaleX, scaleY)); session.Transform = Matrix3x2.Multiply(session.Transform, Matrix3x2.CreateTranslation(-(offsetX * size.X), -(offsetY * size.Y))); foreach (var builder in strokes) { PencilCanvas.DrawPath(session, builder, size); } } using (var session = canvas2.CreateDrawingSession()) { session.DrawImage(bitmap); session.DrawImage(canvas1); } bitmap.Dispose(); using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite)) { await canvas2.SaveAsync(stream, CanvasBitmapFileFormat.Jpeg /*, 0.77f*/); } canvas2.Dispose(); canvas1.Dispose(); return(file); }
public static async Task <StorageFile> CropAsync(StorageFile sourceFile, StorageFile file, Rect cropRectangle, int min = 1280, int max = 0, double quality = 0.77, BitmapRotation rotation = BitmapRotation.None, BitmapFlip flip = BitmapFlip.None) { if (file == null) { file = await ApplicationData.Current.TemporaryFolder.CreateFileAsync("crop.jpg", CreationCollisionOption.ReplaceExisting); } using (var fileStream = await OpenReadAsync(sourceFile)) using (var outputStream = await file.OpenAsync(FileAccessMode.ReadWrite)) { var decoder = await BitmapDecoder.CreateAsync(fileStream); var cropWidth = (double)decoder.PixelWidth; var cropHeight = (double)decoder.PixelHeight; if (decoder.PixelWidth > 1280 || decoder.PixelHeight > 1280) { double ratioX = 1280d / cropWidth; double ratioY = 1280d / cropHeight; double ratio = Math.Min(ratioX, ratioY); cropWidth *= ratio; cropHeight *= ratio; } cropRectangle = new Rect( cropRectangle.X * decoder.PixelWidth, cropRectangle.Y * decoder.PixelHeight, cropRectangle.Width * decoder.PixelWidth, cropRectangle.Height * decoder.PixelHeight); if (rotation != BitmapRotation.None) { cropRectangle = RotateArea(cropRectangle, decoder.PixelWidth, decoder.PixelHeight, (int)rotation); } if (flip == BitmapFlip.Horizontal) { cropRectangle = FlipArea(cropRectangle, decoder.PixelWidth); } var(scaledCrop, scaledSize) = Scale(cropRectangle, new Size(decoder.PixelWidth, decoder.PixelHeight), new Size(cropWidth, cropHeight), min, max); var bounds = new BitmapBounds(); bounds.X = (uint)scaledCrop.X; bounds.Y = (uint)scaledCrop.Y; bounds.Width = (uint)scaledCrop.Width; bounds.Height = (uint)scaledCrop.Height; var transform = new BitmapTransform(); transform.ScaledWidth = (uint)scaledSize.Width; transform.ScaledHeight = (uint)scaledSize.Height; transform.Bounds = bounds; transform.InterpolationMode = BitmapInterpolationMode.Linear; transform.Rotation = rotation; transform.Flip = flip; var pixelData = await decoder.GetSoftwareBitmapAsync(decoder.BitmapPixelFormat, decoder.BitmapAlphaMode, transform, ExifOrientationMode.RespectExifOrientation, ColorManagementMode.DoNotColorManage); var propertySet = new BitmapPropertySet(); var qualityValue = new BitmapTypedValue(quality, PropertyType.Single); propertySet.Add("ImageQuality", qualityValue); var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, outputStream); encoder.SetSoftwareBitmap(pixelData); await encoder.FlushAsync(); } return(file); }
private async void Flip_Click(object sender, RoutedEventArgs e) { var flip = _flip; var rotation = _rotation; var proportions = Cropper.Proportions; var rectangle = FlipArea(Cropper.CropRectangle); switch (rotation) { case BitmapRotation.Clockwise90Degrees: case BitmapRotation.Clockwise270Degrees: switch (flip) { case BitmapFlip.None: flip = BitmapFlip.Vertical; break; case BitmapFlip.Vertical: flip = BitmapFlip.None; break; case BitmapFlip.Horizontal: flip = BitmapFlip.None; rotation = rotation == BitmapRotation.Clockwise90Degrees ? BitmapRotation.Clockwise270Degrees : BitmapRotation.Clockwise90Degrees; break; } break; case BitmapRotation.None: case BitmapRotation.Clockwise180Degrees: switch (flip) { case BitmapFlip.None: flip = BitmapFlip.Horizontal; break; case BitmapFlip.Horizontal: flip = BitmapFlip.None; break; case BitmapFlip.Vertical: flip = BitmapFlip.None; rotation = rotation == BitmapRotation.None ? BitmapRotation.Clockwise180Degrees : BitmapRotation.None; break; } break; } _flip = flip; _rotation = rotation; await Cropper.SetSourceAsync(_file, _rotation, flip, proportions, rectangle); //Transform.ScaleX = _flip == BitmapFlip.Horizontal ? -1 : 1; //Transform.ScaleY = _flip == BitmapFlip.Vertical ? -1 : 1; Flip.IsChecked = _flip != BitmapFlip.None; Canvas.Invalidate(); }
/// <summary> /// Saves and rotates an image. /// </summary> /// <param name="image"> /// The image to rotate. /// </param> /// <param name="rotation"> /// The rotation. /// </param> /// <returns> /// The <see cref="StorageFile"/>. /// </returns> public async Task<StorageFile> SaveAndRotateImage(WriteableBitmap image, BitmapRotation rotation) { var file = await this.SaveCroppedImage(image); var rotated = await this.RotateImage(rotation, file); return rotated; }
/// <summary> /// Rotates the given stream. /// </summary> /// <param name="randomAccessStream">The random access stream.</param> /// <param name="rotation">The rotation.</param> /// <returns>The stream.</returns> public static async Task<InMemoryRandomAccessStream> Rotate(IRandomAccessStream randomAccessStream, BitmapRotation rotation) { var decoder = await BitmapDecoder.CreateAsync(randomAccessStream); var rotatedStream = new InMemoryRandomAccessStream(); var encoder = await BitmapEncoder.CreateForTranscodingAsync(rotatedStream, decoder); encoder.BitmapTransform.Rotation = rotation; encoder.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Fant; await encoder.FlushAsync(); return rotatedStream; }
private async Task<StorageFile> RotateImage(BitmapRotation rotation, IStorageFile file) { int wbRotate = 0; switch (rotation) { case BitmapRotation.Clockwise90Degrees: wbRotate = 90; break; case BitmapRotation.Clockwise180Degrees: wbRotate = 180; break; case BitmapRotation.Clockwise270Degrees: wbRotate = 270; break; } var result = await this.RotateImage(wbRotate, file); return result; }
/// <summary> /// 旋转缩放图片 /// </summary> private static async Task RotationZoomImage(IRandomAccessStream photoStream, StorageFile saveFile, BitmapRotation rotation, int zoomNumber) { try { //var decoder = await BitmapDecoder.CreateAsync(photoStream); //var transform = new BitmapTransform(); //transform.Rotation = rotation; //transform.ScaledWidth = (uint)decoder.PixelWidth; //transform.ScaledHeight = (uint)decoder.PixelHeight; //var pixelData = await decoder.GetPixelDataAsync( // BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, transform, // ExifOrientationMode.RespectExifOrientation, ColorManagementMode.ColorManageToSRgb); //using (var outStream = await saveFile.OpenAsync(FileAccessMode.ReadWrite)) //{ // outStream.Size = 0UL; // var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, outStream); // var newWidth = 0U; // var newHeight = 0U; // if (rotation == BitmapRotation.Clockwise270Degrees || rotation == BitmapRotation.Clockwise90Degrees) // { // newWidth = transform.ScaledHeight; // newHeight = transform.ScaledWidth; // } // else // { // newWidth = transform.ScaledWidth; // newHeight = transform.ScaledHeight; // } // var pixels = pixelData.DetachPixelData(); // if (IsHavePhotoStream == true && IsSupportHWZoom == false) // { // try // { // int depth = 4; // var newPixelData = new byte[(int)(newWidth * newHeight * depth)]; // float offset = (float)((0.5 * zoomNumber - 50) / zoomNumber); // //unsafe // //{ // // fixed (byte* pbSrc = pixels) // // fixed (byte* pbDst = newPixelData) // // { // // IntPtr ptrSrc = (IntPtr)pbSrc; // // IntPtr ptrDst = (IntPtr)pbDst; // // EngineWrapperHelper.HelperObj.Engine.ZoomInImage_RGB32( // // ptrSrc.ToInt32(), // // (int)(newWidth * depth), // // ptrDst.ToInt32(), // // (int)(newWidth * depth), // // (int)newWidth, // // (int)newHeight, // // depth, // // offset, // // offset, // // (float)zoomNumber); // // } // //} // } // catch (Exception ex) // { // LogHelper.AddError(ex); // } // } // encoder.SetPixelData( // BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, // newWidth, newHeight, decoder.DpiX, decoder.DpiY, pixels); // await encoder.FlushAsync(); //} } catch (Exception ex) { } }