none
rotate an image

    Question

  •  I'm writing an image gallery type application.  It displays images that have been scanned into a database. Some of the images have been scanned in upside down.  Others need to be rotated from landscape to portrait.  So, the Silverlight app needs to be able to rotate images in 90 degree increments.  It will also need to export the image to disk.  So, I can't just rotate the image control.  Is it possible to do this using the writablebitmap class?

    Thanks,

     Mike

    Monday, November 16, 2009 11:30 PM

All replies

  • Hi,

    Just a thought. Try using RotateTransform in your image to rotate the images. Check the link below -

    http://blogs.silverlight.net/blogs/msnow/archive/2008/07/14/tip-of-the-day-17-how-to-animate-a-rotating-image.aspx

    Also you can think about saving images to Isolated Stroage. Check the link below-

    http://www.codeproject.com/Articles/38636/Saving-Bitmaps-to-Isolated-Storage-in-Silverlight-3.aspx

    Thanks,

    Pravin

    "Please mark as answered, if this answers your question"

    Tuesday, November 17, 2009 1:07 AM
  • I just need a clarification on whether you want to rotate the Actual Image in Silverlight or want to just rotate the Image control. If you want to rotate the actual image then you have to add your own logic (may be you have to use some bit of WPF component on that). In the other case, you can use RotateTransform to rotate the image control. In this case, your original image will remain same.

    Regarding IsolatedStorage, in general you cannot store more than 1MB data/application/site on that. If you want more storage space then you have to confirm the user to increase the quota, which you can do programmatically. Only thing is, it requires user interaction.

    Tuesday, November 17, 2009 4:09 AM
  • Hi,

    From you description it seems that you want silverlight app to fix the orientation for you.

    The images can be rotated but its you who will decide the degrees and angle for it for that you can use the way microsoft_kc has suggested because those are Human Recognizable Properties

    Tuesday, November 17, 2009 7:28 AM
  • Yes, I need to rotate the data in the bitmap itself.  Here is the workflow.
    1) The page loads and the SL app loads the list of images.
    2) The user clicks on thumbnails to view the image in the main viewer.
    3) If the image is rotated, then the user can use a rotate tool to turn the image upside right.
    4) The user can save the image to the local hard drive as a GIF file.  This is accomplished using SL3's new save file dialog.
    5) The user opens the GIF file on the local hard drive for offline viewing.  The image needs to already be rotated upright because the software the user uses to view the images has no editing features.  Therefore, the images cannot be rotated and saved once they have been exported from the SL app.

    Thanks,

    Mike

    Tuesday, November 17, 2009 12:10 PM
  • You should be able to rotate the image and then render its output to the WriteableBitmap.  After doing that, you can utilize the SaveFileDialog to save the image to the user's machine.

    You can also pass the transform as a parameter to the WriteableBitmap's constructor:

    http://www.wintellect.com/CS/blogs/jprosise/archive/2009/10/29/more-fun-with-silverlight-3-s-writeablebitmap.aspx

    Tuesday, November 17, 2009 12:24 PM
  •  This gets me a lot closer to what I need.  Here is the code I have so far.

         Private Sub RotateImage(ByVal blnRotateLeft As Boolean)
            Dim bm As WriteableBitmap = Nothing
            Dim objTran As RotateTransform = Nothing

            Try
                objTran = New RotateTransform
                objTran.CenterX = 0.5 * imgMainImage.ActualWidth
                objTran.CenterY = 0.5 * imgMainImage.ActualHeight

                If blnRotateLeft = True Then
                    objTran.Angle = -90
                Else
                    objTran.Angle = 90
                End If

                bm = New WriteableBitmap(imgMainImage, objTran)
                imgMainImage.Source = CType(bm, System.Windows.Media.ImageSource)

                bm = Nothing
                GC.Collect()
            Catch ex As Exception
                HandleError(ex.ToString)
            End Try

     

    The only problem that I'm having now is that the image is being cropped when I rotate it.  I suspect that I might be rotating around the wrong point.  When I call the function, it rotates the image 90 degrees.  But, the bottom one-third of the image gets cropped.  I image the part that gets cropped is the difference between the x resolution and the y resolution.  So, if the image were a perfect square, then no cropping would happen.  Is this what is happening here?  Is there a way to resize the writeablebitmap to a square before I perform the rotation so it doesn't crop the image?

    Thanks,

    Mike

    Wednesday, November 18, 2009 3:18 PM
  • Could you elaborate on how to save the contents of a WritableBitmap using the SaveFileDialog?  The SaveFileDialog.Write() method takes a byte array.  How do you convert a WritableBitmap to a byte array?

    Wednesday, November 18, 2009 3:24 PM
  •  I think below is the right answer:

           /// <summary>
            ///pass in a WriteableBitmap and [0,360,-360,270,-270,90,-90,-180,180]
            /// </summary>
            /// <param name="wb"></param>
            /// <param name="CounterclockwiseAngle"></param>
            /// <returns>WriteableBitmap rotated without cropping</returns>
    
            private WriteableBitmap WBRotate(WriteableBitmap wb, int CounterclockwiseAngle)
            {
                int[,] wb_arr = new int[wb.PixelWidth, wb.PixelHeight];
                for (int r = 0; r < wb.PixelHeight; r++)// r=row    c=column
                {
                    for (int c = 0; c < wb.PixelWidth; c++)
                    {
                        wb_arr[c, r] = wb.Pixels[wb.PixelWidth * r + c];
                    }
                }
    
                WriteableBitmap wb2;
                int[,] wb_arr_2;
    
                if (CounterclockwiseAngle == 0 || CounterclockwiseAngle == 360 || CounterclockwiseAngle == -360)//0度 360度
                {
                    wb2 = new WriteableBitmap(wb.PixelWidth, wb.PixelHeight);
                    wb_arr_2 = new int[wb.PixelWidth, wb.PixelHeight];
                    wb_arr_2 = wb_arr;
                }
                else if(CounterclockwiseAngle == 90 || CounterclockwiseAngle == -270)//90 -270//Math.Sin(
                {
                    wb2 = new WriteableBitmap(wb.PixelHeight, wb.PixelWidth);
                    wb_arr_2 = new int[wb.PixelHeight, wb.PixelWidth];
                    for (int c = 0; c < wb_arr.GetLength(0); c++)//width  i
                    {
                        for (int r = 0; r < wb_arr.GetLength(1); r++)//height j
                        {
                            wb_arr_2[r, wb_arr.GetLength(0) - c - 1] = wb_arr[c, r]; //90 Out[j, Right-i-1] = In[i, j]  Right代表真个宽度
                        }
                    }
                }
                else if (CounterclockwiseAngle == 180 || CounterclockwiseAngle == -180)//180 -180
                {
                    wb2 = new WriteableBitmap(wb.PixelWidth, wb.PixelHeight);
                    wb_arr_2 = new int[wb.PixelWidth, wb.PixelHeight];
                    for (int c = 0; c < wb_arr.GetLength(0); c++)//width  i
                    {
                        for (int r = 0; r < wb_arr.GetLength(1); r++)//height j
                        {
                            wb_arr_2[wb_arr.GetLength(0) - c - 1, wb_arr.GetLength(1) - r - 1] = wb_arr[c, r]; //180 Out[Right-i-1, Bottom-j-1] = In[i, j]  
                        }
                    }
                }
                else if (CounterclockwiseAngle == 270 || CounterclockwiseAngle == -90)//270 -90
                {
                    wb2 = new WriteableBitmap(wb.PixelHeight, wb.PixelWidth);
                    wb_arr_2 = new int[wb.PixelHeight, wb.PixelWidth];
                    for (int c = 0; c < wb_arr.GetLength(0); c++)//width  i
                    {
                        for (int r = 0; r < wb_arr.GetLength(1); r++)//height j
                        {
                            wb_arr_2[wb_arr.GetLength(1) - r - 1, c] = wb_arr[c, r]; //270 Out[Bottom-j-1,i] = In[i, j] 
                        }
                    }
                }
                else
                {
                    return null;//如果是其他角度 就直接返回null
                }
                //将二位数组转换成Pixels
                for (int r = 0; r < wb_arr_2.GetLength(1); r++)// r=row    c=column 
                {
                    for (int c = 0; c < wb_arr_2.GetLength(0); c++)
                    {
                        wb2.Pixels[wb2.PixelWidth * r + c] = wb_arr_2[c, r];
                    }
                }
                return wb2;
            }


     my blog: http://www.cnblogs.com/ice6/

    a detailed explianation here:

    http://www.cnblogs.com/ice6/archive/2010/08/19/rotating-an-image-in-silverlight-without-cropping.html

    if someone really need,I will translate it to English

    Thursday, August 19, 2010 11:02 PM