【问题标题】:Rotate a BitmapImage in c#在 C# 中旋转 BitmapImage
【发布时间】:2015-04-24 08:22:51
【问题描述】:

我在使用 BitmapImage 时遇到了一些问题。我有一个 WP8.1 应用程序,我可以在其中拍照、预览和上传。预览显示得很好,旋转和大小都很好,但问题是,要上传它,我传递了对应于 storageFile 的 byte[] ,这是一张大而且方向不太好的图片。我想旋转和缩小storageFile 在从中获取 byte[] 之前。

这是我用来预览/拍摄/转换图片的 sn-p :)

//Récupère la liste des camèras disponibles
    private static async Task<DeviceInformation> GetCameraID(Windows.Devices.Enumeration.Panel desiredCamera)
    {
        DeviceInformation deviceID = (await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture))
            .FirstOrDefault(x => x.EnclosureLocation != null && x.EnclosureLocation.Panel == desiredCamera);

        if (deviceID != null) return deviceID;
        else throw new Exception(string.Format("Camera of type {0} doesn't exist.", desiredCamera));
    }
    //Initialise la caméra
    async private void initCamera()
    {
        //Récupération de la caméra utilisable
        var cameraID = await GetCameraID(Windows.Devices.Enumeration.Panel.Back);
        //Initialise l'objet de capture
        captureManager = new MediaCapture();
        await captureManager.InitializeAsync(new MediaCaptureInitializationSettings
            {
                StreamingCaptureMode = StreamingCaptureMode.Video,
                PhotoCaptureSource = PhotoCaptureSource.VideoPreview,
                AudioDeviceId = string.Empty,
                VideoDeviceId = cameraID.Id
            });

        var maxResolution = captureManager.VideoDeviceController.GetAvailableMediaStreamProperties(MediaStreamType.Photo).Aggregate((i1, i2) => (i1 as VideoEncodingProperties).Width > (i2 as VideoEncodingProperties).Width ? i1 : i2);
        await captureManager.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.Photo, maxResolution);
    }
    //Évènmenet pour le bouton de prise de photo.
    async private void previewpicture_Click(object sender, RoutedEventArgs e)
    {
        //Si la prévisualisation n'est pas lancée
        if (EnPreview == false)
        {
            //On cache les élèments inutilisés.
            tfComment.Visibility = Visibility.Collapsed;
            vbImgDisplay.Visibility = Visibility.Collapsed;
            //On met la prévisualisation dans le bon sens.
            captureManager.SetPreviewRotation(VideoRotation.Clockwise90Degrees);
            //On charge la prévisualisation dans l'élèment de l'image de la fenêtre.
            capturePreview.Source = captureManager;
            //On rend la prévisualisation possible.
            capturePreview.Visibility = Visibility.Visible;
            //Démarre le flux de prévisualisation
            await captureManager.StartPreviewAsync();
            //On précise que la prévisualisation est lancée.
            EnPreview = true;
            //On change le label du bouton
            previewpicture.Label = "Prendre photo";
        }
        //Si la prévisualisation est lancée
        else if (EnPreview == true)
        {
            //Créer le fichier de la photo depuis la mémoire interne de l'application
            StorageFile photoFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("myFirstPhoto.jpg", CreationCollisionOption.ReplaceExisting);
            //Récupère la photo avec le format d'encodage décidé.
            await captureManager.CapturePhotoToStorageFileAsync(ImageEncodingProperties.CreateJpeg(), photoFile);

            // we can also take a photo to memory stream
            InMemoryRandomAccessStream memStream = new InMemoryRandomAccessStream();
            await captureManager.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpegXR(), memStream);
            //Debug.WriteLine(memStream.ToString());
            //Récupère l'image dans un objet image qu'on peut mettre dans le container d'affichage
            BitmapImage bitmapToShow = new BitmapImage(new Uri(photoFile.Path));
            //Met l'image dans le container d'affichage
            imgDisplay.Source = bitmapToShow;
            vbImgDisplay.RenderTransform = new RotateTransform() {CenterX = 0.5, CenterY = 0.5, Angle = 90 };
            //Cache la previsualisation
            capturePreview.Visibility = Visibility.Collapsed;
            //Arrête le flux de prévisualisation
            await captureManager.StopPreviewAsync();
            //rend visible les composants
            tfComment.Visibility = Visibility.Visible;
            vbImgDisplay.Visibility = Visibility.Visible;
            //Converti l'image en tableau de byte
            photoByte = await GetByteFromFile(photoFile);
            //Précise qu'on est plus en prévisualisation
            EnPreview = false;
            previewpicture.Label = "Prévisualiser";
        }
    }
    //Converti un storageFile en Byte[]  
    private async Task<byte[]> GetByteFromFile(StorageFile storageFile)
    {
        var stream = await storageFile.OpenReadAsync();

        using (var dataReader = new DataReader(stream))
        {
            var bytes = new byte[stream.Size];
            await dataReader.LoadAsync((uint)stream.Size);
            dataReader.ReadBytes(bytes);

            return bytes;
        }

    }

提前感谢您的帮助!

【问题讨论】:

    标签: c# xaml windows-phone-8.1 bitmapimage storagefile


    【解决方案1】:

    我建议你使用 Lumia (Nokia) Imaging SDK 来旋转图像,它更容易。

    您可以在此处获取它们: https://www.nuget.org/packages/LumiaImagingSDK/2.0.184

    你可以像这样旋转图像:

    using (var filterEffect = new FilterEffect(source))
    {
        // Initialize the filter and add the filter to the FilterEffect collection to rotate for 15 degrees
        var filter = new RotationFilter(15.0);
    
        filterEffect.Filters = new IFilter[] { filter };
    
        // Create a target where the filtered image will be rendered to
        var target = new WriteableBitmap(width, height);
    
        // Create a new renderer which outputs WriteableBitmaps
        using (var renderer = new WriteableBitmapRenderer(filterEffect, target))
        {
            // Render the image with the filter(s)
            await renderer.RenderAsync();
    
            // Set the output image to Image control as a source
            ImageControl.Source = target;
        }
    
        await SaveEffectAsync(filterEffect, "RotationFilter.jpg", outputImageSize);
    }
    

    【讨论】:

      【解决方案2】:
       //this method will rotate an image any degree
         public static Bitmap RotateImage(Bitmap image, float angle)
          {
              //create a new empty bitmap to hold rotated image
      
              double radius = Math.Sqrt(Math.Pow(image.Width, 2) + Math.Pow(image.Height, 2));
      
              Bitmap returnBitmap = new Bitmap((int)radius, (int)radius);
      
              //make a graphics object from the empty bitmap
              using (Graphics graphic = Graphics.FromImage(returnBitmap))
              {
                  //move rotation point to center of image
                  graphic.TranslateTransform((float)radius / 2, (float)radius / 2);
                  //rotate
                  graphic.RotateTransform(angle);
                  //move image back
                  graphic.TranslateTransform(-(float)image.Width / 2, -(float)image.Height / 2);
                  //draw passed in image onto graphics object
                  graphic.DrawImage(image, new Point(0, 0));
              }
              return returnBitmap;
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-10-20
        • 1970-01-01
        • 2011-01-17
        • 2018-10-14
        • 1970-01-01
        • 1970-01-01
        • 2014-11-13
        相关资源
        最近更新 更多