/// <summary>
		/// Use BitmapTransform to define the region to crop, and then get the pixel data in the region.
		/// If you want to get the pixel data of a scaled image, set the scaledWidth and scaledHeight
		/// of the scaled image.
		/// </summary>
		/// <returns></returns>
		async static private Task<byte[]> GetPixelData(BitmapDecoder decoder, uint startPointX, uint startPointY,
			uint width, uint height, uint scaledWidth, uint scaledHeight)
		{

			BitmapTransform transform = new BitmapTransform();
			BitmapBounds bounds = new BitmapBounds();
			bounds.X = startPointX;
			bounds.Y = startPointY;
			bounds.Height = height;
			bounds.Width = width;
			transform.Bounds = bounds;

			transform.ScaledWidth = scaledWidth;
			transform.ScaledHeight = scaledHeight;

			// Get the cropped pixels within the bounds of transform.
			PixelDataProvider pix = await decoder.GetPixelDataAsync(
				BitmapPixelFormat.Bgra8,
				BitmapAlphaMode.Straight,
				transform,
				ExifOrientationMode.IgnoreExifOrientation,
				ColorManagementMode.ColorManageToSRgb);
			byte[] pixels = pix.DetachPixelData();
			return pixels;
		}
예제 #2
0
        internal static async Task LoadTileImageInternalAsync(string imagePath)
        {
            string tileName = "dreaming";
            uint MaxImageWidth =360;
            uint MaxImageHeight = 600;

            StorageFile origFile = await ApplicationData.Current.LocalFolder.GetFileAsync(imagePath);

            // open file for the new tile image file
            StorageFile tileFile = await Windows.Storage.KnownFolders.PicturesLibrary.CreateFileAsync(tileName, CreationCollisionOption.GenerateUniqueName);
            using (IRandomAccessStream tileStream = await tileFile.OpenAsync(FileAccessMode.ReadWrite))
            {
                // get width and height from the original image
                IRandomAccessStreamWithContentType stream = await origFile.OpenReadAsync();
                ImageProperties properties = await origFile.Properties.GetImagePropertiesAsync();
                uint width = properties.Width;
                uint height = properties.Height;

                // get proper decoder for the input file - jpg/png/gif
                BitmapDecoder decoder = await GetProperDecoder(stream, origFile );
                if (decoder == null) return; // should not happen
                // get byte array of actual decoded image
                PixelDataProvider data = await decoder.GetPixelDataAsync();
                byte[] bytes = data.DetachPixelData();

                // create encoder for saving the tile image
                BitmapPropertySet propertySet = new BitmapPropertySet();
                // create class representing target jpeg quality - a bit obscure, but it works
                BitmapTypedValue qualityValue = new BitmapTypedValue(0.5, PropertyType.Single);
                propertySet.Add("ImageQuality", qualityValue);
                // create the target jpeg decoder
                BitmapEncoder be = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, tileStream, propertySet);
                be.SetPixelData(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Straight, width, height, 96.0, 96.0, bytes);

                // crop the image, if it's too big
                if (width > MaxImageWidth || height > MaxImageHeight)
                {
                    BitmapBounds bounds = new BitmapBounds();
                    if (width > MaxImageWidth)
                    {
                        bounds.Width = MaxImageWidth;
                        bounds.X = (width - MaxImageWidth) / 2;
                    }
                    else bounds.Width = width;
                    if (height > MaxImageHeight)
                    {
                        bounds.Height = MaxImageHeight;
                        bounds.Y = (height - MaxImageHeight) / 2;
                    }
                    else bounds.Height = height;
                    be.BitmapTransform.Bounds = bounds;
                }
                // save the target jpg to the file
                await be.FlushAsync();
            }
           
        }
예제 #3
0
        public static async Task<byte[]> CropImage(byte[] stream, Crop crop)
        {
            byte[] byteArray = null;

            var imageStream = new MemoryStream(stream);

            var fileStream = imageStream.AsRandomAccessStream();
            BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream);
            InMemoryRandomAccessStream ras = new InMemoryRandomAccessStream();
            BitmapEncoder enc = await BitmapEncoder.CreateForTranscodingAsync(ras, decoder);

            BitmapBounds bounds = new BitmapBounds();
            bounds.Height = (uint)crop.Height;
            bounds.Width = (uint)crop.Width;
            bounds.X = (uint)crop.X;
            bounds.Y = (uint)crop.Y;

            enc.BitmapTransform.Bounds = bounds;
            enc.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Linear;
            enc.IsThumbnailGenerated = false;

            try
            {
                await enc.FlushAsync();
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Error croping image", ex);
            }

            byteArray = new byte[ras.Size];
            DataReader dataReader = new DataReader(ras.GetInputStreamAt(0));
            await dataReader.LoadAsync((uint)ras.Size);
            dataReader.ReadBytes(byteArray);

            return byteArray;
        }
예제 #4
0
        /// <summary>
        ///     Helper to get the correct Bounds for 15:9 screens and to set finalPhotoAreaBorder values
        /// </summary>
        /// <returns></returns>
        private BitmapBounds GetFifteenByNineBounds()
        {
            var bounds = new BitmapBounds();

            //image size is raw pixels, so we need also here raw pixels
            var logicalPixelWidth = Window.Current.Bounds.Width;
            var logicalPixelHeight = Window.Current.Bounds.Height;

            var rawPerViewPixels = DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;
            var rawPixelHeight = logicalPixelHeight*rawPerViewPixels;
            var rawPixelWidth = logicalPixelWidth*rawPerViewPixels;

            //calculate scale factor of UniformToFill Height (remember, we rotated the preview)
            var scaleFactorVisualHeight = maxResolution().Width/rawPixelHeight;

            //calculate the visual Width 
            //(because UniFormToFill scaled the previewElement Width down to match the previewElement Height)
            var visualWidth = maxResolution().Height/scaleFactorVisualHeight;

            //calculate cropping area for 15:9
            var scaledBoundsWidth = maxResolution().Height;
            var scaledBoundsHeight = (scaledBoundsWidth/9)*15;

            //we are starting at the top of the image
            bounds.Y = 0;
            //cropping the image width
            bounds.X = 0;
            bounds.Height = scaledBoundsHeight;
            bounds.Width = scaledBoundsWidth;

            //set finalPhotoAreaBorder values that shows the user the area that is captured
            //finalPhotoAreaBorder.Width = (scaledBoundsWidth / scaleFactorVisualHeight) / rawPerViewPixels;
            //finalPhotoAreaBorder.Height = (scaledBoundsHeight / scaleFactorVisualHeight) / rawPerViewPixels;
            //finalPhotoAreaBorder.Margin = new Thickness(
            //                                Math.Floor(((rawPixelWidth - visualWidth) / 2) / rawPerViewPixels),
            //                                0,
            //                                Math.Floor(((rawPixelWidth - visualWidth) / 2) / rawPerViewPixels),
            //                                0);
            //finalPhotoAreaBorder.Visibility = Visibility.Visible;

            return bounds;
        }
예제 #5
0
        private static async Task<StorageFile> GenerateResizedImageAsync(StorageFile inputFile, uint width, uint height, uint edgePadding = 5, uint bottomPadding = 20, NameCollisionOption collisionOption = NameCollisionOption.ReplaceExisting)
        {
            try
            {
                string fileName = inputFile.DisplayName + width + "x" + height;
                string extension = inputFile.Name.Substring(inputFile.Name.LastIndexOf('.'));

                string folder = inputFile.Path.Substring(0, inputFile.Path.LastIndexOf('\\'));
                var outputFolder = await StorageFolder.GetFolderFromPathAsync(folder);
                var newFile = await outputFolder.CreateFileAsync(fileName + extension, CreationCollisionOption.ReplaceExisting);

                var inputStream = await inputFile.OpenAsync(Windows.Storage.FileAccessMode.Read);
                var outputStream = await newFile.OpenTransactedWriteAsync();

                var inMemStream = new InMemoryRandomAccessStream();
                var decoder = await BitmapDecoder.CreateAsync(inputStream);
                var encoder = await BitmapEncoder.CreateForTranscodingAsync(inMemStream, decoder);

                // Find aspect ratio for resize
                float nPercentW = (((float)width - (edgePadding * 2)) / (float)decoder.PixelWidth);
                float nPercentH = (((float)height - (edgePadding * 2)) / (float)decoder.PixelHeight);
                float nPercent = nPercentH < nPercentW ? nPercentH : nPercentW;

                // Scale height and width
                if (nPercent < 1)
                {
                    encoder.BitmapTransform.ScaledHeight = (uint)(decoder.PixelHeight * nPercent);
                    encoder.BitmapTransform.ScaledWidth = (uint)(decoder.PixelWidth * nPercent);
                }

                // Image may still exceed intended bounds, resize as appropriate
                if (encoder.BitmapTransform.ScaledWidth > width || encoder.BitmapTransform.ScaledHeight > height)
                {
                    BitmapBounds bounds = new BitmapBounds();
                    if (encoder.BitmapTransform.ScaledWidth > width)
                    {
                        bounds.Width = width;
                        bounds.X = (encoder.BitmapTransform.ScaledWidth - width) / 2;
                    }
                    else
                        bounds.Width = encoder.BitmapTransform.ScaledWidth;
                    if (encoder.BitmapTransform.ScaledHeight > height)
                    {
                        bounds.Height = height;
                        bounds.Y = (encoder.BitmapTransform.ScaledHeight - height) / 2;
                    }
                    else
                        bounds.Height = encoder.BitmapTransform.ScaledHeight;
                    encoder.BitmapTransform.Bounds = bounds;
                }
                await encoder.FlushAsync();

                var outDecoder = await BitmapDecoder.CreateAsync(inMemStream);
                var outEncoder = await BitmapEncoder.CreateForTranscodingAsync(outputStream.Stream, outDecoder);

                var transparentBytes = GenerateTransparentBitmap(width, height);

                PixelDataProvider data = await outDecoder.GetPixelDataAsync();
                uint heightOffset = (height - outDecoder.PixelHeight) / 2 - bottomPadding;
                uint widthOffset = (width - outDecoder.PixelWidth) / 2;
                byte[] bytes = MergePixelArrays(transparentBytes, width, height, data.DetachPixelData(), outDecoder.PixelWidth, outDecoder.PixelHeight, widthOffset, heightOffset);
                outEncoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, width, height, 72.0, 72.0, bytes);

                await outEncoder.FlushAsync();
                return newFile;
            }
            catch (Exception)
            {

            }

            return null;
        }
예제 #6
0
        async public void SaveAndCropCover(StorageFile originalImgFile)
        {


            using (IRandomAccessStream stream = await originalImgFile.OpenReadAsync())
            {


                // Create a decoder from the stream. With the decoder, we can get  
                // the properties of the image. 
                BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);




                var shortSide = Math.Min(decoder.PixelWidth, decoder.PixelHeight);
                double scale = Math.Min(1, shortSide / 480);
                Size corpSize = new Size(shortSide, shortSide);
                Point startPoint = new Point((decoder.PixelWidth - shortSide) / 2, (decoder.PixelHeight - shortSide) / 2);


                // Source: https://code.msdn.microsoft.com/windowsapps/CSWin8AppCropBitmap-52fa1ad7

                if (double.IsNaN(scale) || double.IsInfinity(scale))
                {
                    scale = 1;
                }


                // Convert start point and size to integer. 
                uint startPointX = (uint)Math.Floor(startPoint.X * scale);
                uint startPointY = (uint)Math.Floor(startPoint.Y * scale);
                uint height = (uint)Math.Floor(corpSize.Height * scale);
                uint width = (uint)Math.Floor(corpSize.Width * scale);





                // The scaledSize of original image. 
                uint scaledWidth = (uint)Math.Floor(decoder.PixelWidth * scale);
                uint scaledHeight = (uint)Math.Floor(decoder.PixelHeight * scale);



                // Refine the start point and the size.  
                if (startPointX + width > scaledWidth)
                {
                    startPointX = scaledWidth - width;
                }


                if (startPointY + height > scaledHeight)
                {
                    startPointY = scaledHeight - height;
                }


                // Create cropping BitmapTransform and define the bounds. 
                BitmapTransform transform = new BitmapTransform();
                BitmapBounds bounds = new BitmapBounds();
                bounds.X = startPointX;
                bounds.Y = startPointY;
                bounds.Height = height;
                bounds.Width = width;
                transform.Bounds = bounds;


                transform.ScaledWidth = scaledWidth;
                transform.ScaledHeight = scaledHeight;

                // Get the cropped pixels within the bounds of transform. 
                PixelDataProvider pix = await decoder.GetPixelDataAsync(
                    BitmapPixelFormat.Bgra8,
                    BitmapAlphaMode.Straight,
                    transform,
                    ExifOrientationMode.RespectExifOrientation,
                    ColorManagementMode.ColorManageToSRgb);
                byte[] pixels = pix.DetachPixelData();


                // Stream the bytes into a WriteableBitmap 
                WriteableBitmap cropBmp = new WriteableBitmap((int)width, (int)height);
                Stream pixStream = cropBmp.PixelBuffer.AsStream();
                pixStream.Write(pixels, 0, (int)(width * height * 4));

                this.SaveCover(cropBmp);
            }
        }
예제 #7
0
 private async void BitmapTransform(string filePath)
 {
     var client = new HttpClient();
     var stream = await client.GetStreamAsync(filePath);
     var memStream = new MemoryStream();
     await stream.CopyToAsync(memStream);
     memStream.Position = 0;
     var decoder = await BitmapDecoder.CreateAsync(memStream.AsRandomAccessStream());
     var ras = new InMemoryRandomAccessStream();
     var enc = await BitmapEncoder.CreateForTranscodingAsync(ras, decoder);
     var frame = await decoder.GetFrameAsync(0);
     enc.BitmapTransform.ScaledHeight = frame.PixelHeight;
     enc.BitmapTransform.ScaledWidth = frame.PixelWidth;
     var bounds = new BitmapBounds
     {
         Height = 80,
         Width = frame.PixelWidth,
         X = 0,
         Y = 0
     };
     enc.BitmapTransform.Bounds = bounds;
     try
     {
         await enc.FlushAsync();
     }
     catch (Exception ex)
     {
         Debug.WriteLine(ex.ToString());
     }
     var bImg = BitmapFactory.New((int) frame.PixelWidth, (int) frame.PixelHeight);
     using (bImg.GetBitmapContext())
     {
         bImg = await BitmapFactory.New((int) frame.PixelWidth, (int) frame.PixelHeight).FromStream(ras);
         bImg.ForEach(
             (x, y, color) => color.ToString().Equals("#FFCECECE")
                 ? Color.FromArgb(80, 0, 0, 0)
                 : Colors.WhiteSmoke);
     }
     BorderBrushStreamPlayer.ImageSource = bImg;
 }
예제 #8
0
파일: Service.cs 프로젝트: liquidboy/X
        //public static async Task<bool> GenerateImageAsync(InMemoryRandomAccessStream ms, string newImageName)
        //{
        //    using (var a = ms.AsStream())
        //    {
        //        byte[] b = new byte[a.Length];
        //        await a.ReadAsync(b, 0, (int)a.Length);
        //        StorageFile sampleFile = await _originalFolder.CreateFileAsync(newImageName);
        //        await FileIO.WriteBytesAsync(sampleFile, b);
        //    }

        //    return true;
        //}

        //public async Task<bool> GenerateResizedImageAsyncOld(int longWidth, double srcWidth, double srcHeight, InMemoryRandomAccessStream srcMemoryStream, string newImageName, location subFolder, int longHeight = 0)
        //{
        //    if (_localFolder == null) InitFolders();

        //    try
        //    {
        //        int width = 0, height = 0;
        //        double factor = srcWidth / srcHeight;
        //        if (factor < 1)
        //        {
        //            height = longWidth;
        //            width = (int)(longWidth * factor);
        //        }
        //        else
        //        {
        //            width = longWidth;
        //            height = (int)(longWidth / factor);
        //        }

        //        if (longHeight > 0)
        //        {
        //            width = longWidth;
        //            height = longHeight;
        //        }
                
        //        WriteableBitmap wb = await BitmapFactory.New((int)srcWidth, (int)srcHeight).FromStream(srcMemoryStream);
                
        //        //WRITEABLE BITMAP IS THROWING AN ERROR

        //        var wbthumbnail = wb.Resize(width, height, Windows.UI.Xaml.Media.Imaging.WriteableBitmapExtensions.Interpolation.Bilinear);

        //        switch (subFolder)
        //        {
        //            case location.MediumFolder:
        //                StorageFile sampleFile1 = await _mediumFolder.CreateFileAsync(newImageName, CreationCollisionOption.ReplaceExisting);
        //                await wbthumbnail.SaveToFile(sampleFile1, BitmapEncoder.PngEncoderId);
        //                break;
        //            case location.ThumbFolder:
        //                StorageFile sampleFile2 = await _thumbFolder.CreateFileAsync(newImageName, CreationCollisionOption.ReplaceExisting);
        //                await wbthumbnail.SaveToFile(sampleFile2, BitmapEncoder.PngEncoderId);
        //                break;
        //            case location.TileFolder:
        //                StorageFile sampleFile3 = await _tileFolder.CreateFileAsync(newImageName, CreationCollisionOption.ReplaceExisting);
        //                await wbthumbnail.SaveToFile(sampleFile3, BitmapEncoder.PngEncoderId);
        //                break;
        //        }

        //        return true;
        //    }
        //    catch (Exception ex)
        //    {
        //        return false;
        //    }


        //}

        public async Task<bool> GenerateResizedImageAsync(int longWidth, double srcWidth, double srcHeight, InMemoryRandomAccessStream srcMemoryStream, string newImageName, location subFolder, int longHeight = 0)
        {
            if (_localFolder == null) InitFolders();
            if (srcMemoryStream.Size == 0) return false;

            try
            {
                int width = 0, height = 0;
                double factor = srcWidth / srcHeight;
                if (factor < 1)
                {
                    height = longWidth;
                    width = (int)(longWidth * factor);
                }
                else
                {
                    width = longWidth;
                    height = (int)(longWidth / factor);
                }

                if (longHeight > 0)
                {
                    width = longWidth;
                    height = longHeight;
                }



                if (subFolder == location.MediumFolder) {
                    WriteableBitmap wb = await BitmapFactory.New((int)srcWidth, (int)srcHeight).FromStream(srcMemoryStream);
                    var wbthumbnail = wb.Resize(width, height, Windows.UI.Xaml.Media.Imaging.WriteableBitmapExtensions.Interpolation.Bilinear);
                    StorageFile sampleFile1 = await _mediumFolder.CreateFileAsync(newImageName, CreationCollisionOption.ReplaceExisting);
                    await wbthumbnail.SaveToFile(sampleFile1, BitmapEncoder.PngEncoderId);
                }
                else if (subFolder == location.ThumbFolder)
                {
                    WriteableBitmap wb = await BitmapFactory.New((int)srcWidth, (int)srcHeight).FromStream(srcMemoryStream);
                    var wbthumbnail = wb.Resize(width, height, Windows.UI.Xaml.Media.Imaging.WriteableBitmapExtensions.Interpolation.Bilinear);
                    StorageFile sampleFile2 = await _thumbFolder.CreateFileAsync(newImageName, CreationCollisionOption.ReplaceExisting);
                    await wbthumbnail.SaveToFile(sampleFile2, BitmapEncoder.PngEncoderId);
                }
                else if (subFolder == location.TileFolder) {

                    //https://social.msdn.microsoft.com/Forums/en-US/490b9c01-db4b-434f-8aff-d5c495e67e55/how-to-crop-an-image-using-bitmaptransform?forum=winappswithcsharp

                    BitmapDecoder decoder = await BitmapDecoder.CreateAsync(srcMemoryStream);

                    using (InMemoryRandomAccessStream ras = new InMemoryRandomAccessStream()) { 
                        BitmapEncoder enc = await BitmapEncoder.CreateForTranscodingAsync(ras, decoder);

                        var h = longHeight / srcHeight;
                        var w = longWidth / srcWidth;
                        var r = Math.Max(h, w);
                        
                        enc.BitmapTransform.ScaledWidth = (uint)(srcWidth * r);
                        enc.BitmapTransform.ScaledHeight = (uint)(srcHeight * r);
                    
                        BitmapBounds bounds = new BitmapBounds();
                        bounds.Width = (uint)longWidth;
                        bounds.Height = (uint)longHeight;
                        bounds.X = 0;
                        bounds.Y = 0;
                        enc.BitmapTransform.Bounds = bounds;

                        await enc.FlushAsync();

                        WriteableBitmap wb = await BitmapFactory.New(longWidth, longHeight).FromStream(ras);

                        StorageFile sampleFile3 = await _tileFolder.CreateFileAsync(newImageName, CreationCollisionOption.ReplaceExisting);
                        await wb.SaveToFile(sampleFile3, BitmapEncoder.PngEncoderId);
                    }
                    
                }
                
            
            

                return true;
            }
            catch //(Exception ex)
            {
                return false;
            }


        }
예제 #9
0
        private Rectangle ConvertPreviewToUiRectangle(BitmapBounds faceBoxInPreviewCoordinates)
        {
            var result = new Rectangle();

            var previewStream = mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview) as VideoEncodingProperties;

            // If there is no available information about the preview, return an empty rectangle, as re-scaling to the screen coordinates will be impossible
            if (previewStream == null)
                return result;

            // Similarly, if any of the dimensions is zero (which would only happen in an error case) return an empty rectangle
            if (previewStream.Width == 0 || previewStream.Height == 0)
                return result;

            double streamWidth = previewStream.Width;
            double streamHeight = previewStream.Height;

            // Get the rectangle that is occupied by the actual video feed
            var previewInUI = GetPreviewStreamRectInControl(previewStream, PreviewControl);

            // Scale the width and height from preview stream coordinates to window coordinates
            result.Width = (faceBoxInPreviewCoordinates.Width / streamWidth) * previewInUI.Width;
            result.Height = (faceBoxInPreviewCoordinates.Height / streamHeight) * previewInUI.Height;

            // Scale the X and Y coordinates from preview stream coordinates to window coordinates
            var x = (faceBoxInPreviewCoordinates.X / streamWidth) * previewInUI.Width;
            var y = (faceBoxInPreviewCoordinates.Y / streamHeight) * previewInUI.Height;
            Canvas.SetLeft(result, x);
            Canvas.SetTop(result, y);

            return result;
        }
예제 #10
0
        async void cropImage(IRandomAccessStream inputStream, uint bw, uint bh, uint w, uint h, string fname, StorageFolder folder)
        {

            BitmapDecoder decoder = await BitmapDecoder.CreateAsync(inputStream);

            InMemoryRandomAccessStream ras = new InMemoryRandomAccessStream();
            BitmapEncoder enc = await BitmapEncoder.CreateForTranscodingAsync(ras, decoder);

            BitmapBounds bounds = new BitmapBounds();
            bounds.Height = h;
            bounds.Width = w;
            bounds.X = bw;
            bounds.Y = bh;
            
            enc.BitmapTransform.Bounds = bounds;

            // write out to the stream
            try
            {
                await enc.FlushAsync();
            }
            catch (Exception ex)
            {
                string s = ex.ToString();
            }

 
            ras.Seek(0);
            // render the stream to the screen
            BitmapImage bImg = new BitmapImage();
            bImg.SetSource(ras);

            imgHidden.Source = bImg; // image element in xaml


            if (folder != null)
            {

                StorageFile file1 = await folder.CreateFileAsync(fname + "."+imgFormat, CreationCollisionOption.ReplaceExisting);

                using (var fileStream1 = await file1.OpenAsync(FileAccessMode.ReadWrite))
                {
                    await RandomAccessStream.CopyAndCloseAsync(ras.GetInputStreamAt(0), fileStream1.GetOutputStreamAt(0));
                }

            }

        }
        private async Task<InMemoryRandomAccessStream> ResizeImage(InMemoryRandomAccessStream stream, Size requiredSize)
        {
            // Make a decoder for the current stream
            BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);

            uint imageHeight = decoder.PixelHeight;
            uint imageWidth = decoder.PixelWidth;

            double widthRatio = imageWidth / requiredSize.Width;
            double heightRatio = imageHeight / requiredSize.Height;
               
            uint outputHeight = imageHeight;
            uint outputWidth = imageWidth;
            bool centerOnX = false;

            if (widthRatio < heightRatio)
            {
                outputHeight = (uint)(imageHeight / widthRatio);
                outputWidth = (uint)requiredSize.Width;
                centerOnX = false;
            }
            else
            {
                outputWidth = (uint)(imageWidth / heightRatio);
                outputHeight = (uint)requiredSize.Height;
                centerOnX = true;
            }

            // Make an output stream and an encoder
            InMemoryRandomAccessStream outputStream = new InMemoryRandomAccessStream();
            BitmapEncoder enc = await BitmapEncoder.CreateForTranscodingAsync(outputStream, decoder);

            // convert the entire bitmap to a 125px by 125px bitmap
            enc.BitmapTransform.ScaledHeight = outputHeight;
            enc.BitmapTransform.ScaledWidth = outputWidth;
            BitmapBounds bound = new BitmapBounds();
            bound.Height = (uint)requiredSize.Height;
            bound.Width = (uint)requiredSize.Width;

            // Choose Fant for quality over perf.
            enc.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Fant;

            if(centerOnX)
            {
                int width = ((int)outputWidth / 2) - ((int)bound.Width / 2);
                bound.X = (uint)(width > 0 ? width : 0);
            }
            else
            {
                int height = ((int)outputHeight / 2) - ((int)bound.Height / 2);
                bound.Y = (uint)(height > 0 ? height : 0);
            }
            enc.BitmapTransform.Bounds = bound;

            // Do it
            await enc.FlushAsync();

            // Return the new stream
            return outputStream;
        }
        /// <summary>
        ///     Helper to get the correct Bounds for 15:9 screens and to set finalPhotoAreaBorder values
        /// </summary>
        /// <returns></returns>
        private BitmapBounds GetFifteenByNineBounds()
        {
            var bounds = new BitmapBounds();

            // image size is raw pixels, so we need also here raw pixels
            var logicalPixelWidth = Window.Current.Bounds.Width;
            var logicalPixelHeight = Window.Current.Bounds.Height;

            var rawPerViewPixels = DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;
            var rawPixelHeight = logicalPixelHeight * rawPerViewPixels;
            var rawPixelWidth = logicalPixelWidth * rawPerViewPixels;

            // calculate scale factor of UniformToFill Height (remember, we rotated the preview)
            var scaleFactorVisualHeight = this.maxResolution().Width / rawPixelHeight;

            // calculate the visual Width 
            // (because UniFormToFill scaled the previewElement Width down to match the previewElement Height)
            var visualWidth = this.maxResolution().Height / scaleFactorVisualHeight;

            // calculate cropping area for 15:9
            var scaledBoundsWidth = this.maxResolution().Height;
            var scaledBoundsHeight = (scaledBoundsWidth / 9) * 15;

            // we are starting at the top of the image
            bounds.Y = 0;

            // cropping the image width
            bounds.X = 0;
            bounds.Height = scaledBoundsHeight;
            bounds.Width = scaledBoundsWidth;

            return bounds;
        }
예제 #13
0
        private async Task<InMemoryRandomAccessStream> ResizeImage(InMemoryRandomAccessStream stream, Size requiredSize)
        {
            // Make a decoder for the current stream
            BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);

            uint imageHeight = decoder.PixelHeight;
            uint imageWidth = decoder.PixelWidth;

            double widthRatio = imageWidth / requiredSize.Width;
            double heightRatio = imageHeight / requiredSize.Height;
               
            uint outputHeight = imageHeight;
            uint outputWidth = imageWidth;

            if (widthRatio < heightRatio)
            {
                outputHeight = (uint)(imageHeight / widthRatio);
                outputWidth = (uint)requiredSize.Width;
            }
            else
            {
                outputWidth = (uint)(imageWidth / heightRatio);
                outputHeight = (uint)requiredSize.Height;
            }

            // Make an output stream and an encoder
            InMemoryRandomAccessStream outputStream = new InMemoryRandomAccessStream();
            BitmapEncoder enc = await BitmapEncoder.CreateForTranscodingAsync(outputStream, decoder);

            // convert the entire bitmap to a 125px by 125px bitmap
            enc.BitmapTransform.ScaledHeight = outputHeight;
            enc.BitmapTransform.ScaledWidth = outputWidth;
            BitmapBounds bound = new BitmapBounds();
            bound.Height = (uint)requiredSize.Height;
            bound.Width = (uint)requiredSize.Width;
            enc.BitmapTransform.Bounds = bound;

            // Do it
            await enc.FlushAsync();

            // Return the new stream
            return outputStream;
        }
예제 #14
0
        public static async Task CropandScaleAsync(StorageFile source, StorageFile dest, Point startPoint, Size size, double m_scaleFactor)
        {
            uint startPointX = (uint)Math.Floor(startPoint.X);
            uint startPointY = (uint)Math.Floor(startPoint.Y);
            uint height = (uint)Math.Floor(size.Height);
            uint width = (uint)Math.Floor(size.Width);
            using (IRandomAccessStream sourceStream = await source.OpenReadAsync(),
                destStream = await dest.OpenAsync(FileAccessMode.ReadWrite))
            {
                BitmapDecoder decoder = await BitmapDecoder.CreateAsync(sourceStream);
                var m_displayHeightNonScaled = decoder.OrientedPixelHeight;
                var m_displayWidthNonScaled = decoder.OrientedPixelWidth;

                // Use the native (no orientation applied) image dimensions because we want to handle
                // orientation ourselves.
                BitmapTransform transform = new BitmapTransform();
                BitmapBounds bounds = new BitmapBounds();

                bounds.X = (uint)(startPointX * m_scaleFactor);
                bounds.Y = (uint)(startPointY * m_scaleFactor);
                bounds.Height = (uint)(height * m_scaleFactor);
                bounds.Width = (uint)(width * m_scaleFactor);
                transform.Bounds = bounds;

                // Scaling occurs before flip/rotation, therefore use the original dimensions
                // (no orientation applied) as parameters for scaling.
                transform.ScaledHeight = (uint)(decoder.PixelHeight * m_scaleFactor);
                transform.ScaledWidth = (uint)(decoder.PixelWidth * m_scaleFactor);
                transform.Rotation = BitmapRotation.None;

                // Fant is a relatively high quality interpolation mode.
                transform.InterpolationMode = BitmapInterpolationMode.Fant;
                BitmapPixelFormat format = decoder.BitmapPixelFormat;
                BitmapAlphaMode alpha = decoder.BitmapAlphaMode;

                // Set the encoder's destination to the temporary, in-memory stream.
                PixelDataProvider pixelProvider = await decoder.GetPixelDataAsync(
                        format,
                        alpha,
                        transform,
                        ExifOrientationMode.IgnoreExifOrientation,
                        ColorManagementMode.ColorManageToSRgb
                        );

                byte[] pixels = pixelProvider.DetachPixelData();


                Guid encoderID = Guid.Empty;

                switch (dest.FileType.ToLower())
                {
                    case ".png":
                        encoderID = BitmapEncoder.PngEncoderId;
                        break;
                    case ".bmp":
                        encoderID = BitmapEncoder.BmpEncoderId;
                        break;
                    default:
                        encoderID = BitmapEncoder.JpegEncoderId;
                        break;
                }

                // Write the pixel data onto the encoder. Note that we can't simply use the
                // BitmapTransform.ScaledWidth and ScaledHeight members as the user may have
                // requested a rotation (which is applied after scaling).
                var encoder = await BitmapEncoder.CreateAsync(encoderID, destStream);

                encoder.SetPixelData(
                    format,
                    alpha,
                    (bounds.Width),
                    (bounds.Height),
                    decoder.DpiX,
                    decoder.DpiY,
                    pixels
                    );

                await encoder.FlushAsync();
            }
        }