Page 1 of 8 in the Programming category Next Page
# Friday, March 19, 2010

I needed to resize an image in Silverlight and then save it out as a JPEG. I could have just used a transform on it then rendered it to a WriteableBitmap but the transforms were optimized for realtime performance and doesn't work too well when you need to maintain quality.

I stumbled upon a Bicubic Resize code in a library called AForge.Net and it was in C#, so it was simple enough for me to convert it to VB for me to use it in Silverlight. And since I DIDN'T find a lot of Bicubic Interpolation .Net resize code on the net, I'm gonna just put this copy up here.

As a bonus I kept on my comments in so you guys can see what was going through my head as I was working my way through the code.

Bicubic Interpolation
''' <summary>
  ''' Bicubically resize the src bitmap to the dest bitmap
  ''' </summary>
  ''' <param name="src"></param>
  ''' <param name="dest">Destination Bitmap, should be initialized to the requested size.</param>
  ''' <remarks>Original Source For This Function - http://www.codeproject.com/KB/recipes/aforge.aspx</remarks>    
  Sub Resize(ByVal src As Imaging.WriteableBitmap, ByVal dest As Imaging.WriteableBitmap)

      Dim startTime As DateTime = Now


      Dim srcwidth As Integer = src.PixelWidth
      Dim srcHeight As Integer = src.PixelHeight

      Dim destWidth As Integer = dest.PixelWidth
      Dim destHeight As Integer = dest.PixelHeight

      Dim xFactor As Double = srcwidth / destWidth
      Dim yFactor As Double = srcHeight / destHeight

      'Coordinates of src points and  coefficients.. WTF?
      Dim ox, oy, dx, dy, k1, k2 As Double
      Dim ox1, oy1, ox2, oy2 As Integer

      'new color values
      Dim r, g, b As Double

      Dim xmax As Integer = srcwidth - 1
      Dim ymax As Integer = srcHeight - 1

      For y As Integer = 0 To destHeight - 1
          'this is getting the original Y pixel if I'm not mistaken
          oy = y * yFactor - 0.5F
          'WHY is this necessary?
          oy1 = oy
          'WTF? It's getting the FRACTIONAL difference between
          'oy and oy1?
          dy = oy - oy1


          For x As Integer = 0 To destWidth - 1
              'same WTF as with the Y values,
              'maybe will make more sense later?
              ox = x * xFactor - 0.5F
              ox1 = ox
              dx = ox - ox1

              r = 0
              g = 0
              b = 0


              'this loop is to gather the interpolated
              'values of 2 pixels surrounding the current one
              For n As Integer = -1 To 2
                  'this gets the Y coefficient

                  k1 = BicubicKernel(dy - n)

                  'this seems to be getting the new
                  'Y pixel where the interpolated
                  'value comes from
                  oy2 = oy1 + n

                  'this is to ensure we're in the right spot
                  If oy2 < 0 Then
                      oy2 = 0
                  ElseIf oy2 > ymax Then
                      oy2 = ymax
                  End If

                  For m As Integer = -1 To 2
                      'for X coefficient
                      k2 = k1 * BicubicKernel(m - dx)

                      ox2 = ox1 + m

                      If ox2 < 0 Then
                          ox2 = 0
                      ElseIf ox2 > xmax Then
                          ox2 = xmax
                      End If

                      'get original pixel color
                      ' Dim origColor As Color = source.GetPixel(ox2, oy2)

                      'writablebitmap pixel is AARRGGBB
                      Dim srcColor As Integer = src.Pixels(ox2 + (srcwidth * oy2))


                      'set interpolated values
                      r += k2 * ((srcColor >> 16) And &HFF)
                      g += k2 * ((srcColor >> 8) And &HFF)
                      b += k2 * (srcColor And &HFF)
                  Next
              Next

              'after calculating coefficients we have our new color               
              dest.Pixels(x + (destWidth * y)) = &HFF000000 Or (r << 16) Or (g << 8) Or b


          Next
      Next
      dest.Invalidate()
      Dim endTime As DateTime = Now
      Diagnostics.Debug.WriteLine(String.Format("Time taken to squish {0}x{1} to {2}x{3} : {4} seconds", srcwidth, srcHeight, destWidth, destHeight, endTime.Subtract(startTime).TotalSeconds))

  End Sub

  Shared Function BicubicKernel(ByVal x As Double) As Double

      If x > 2.0 Then
          Return 0.0
      End If

      Dim a, b, c, d As Double
      Dim xm1 As Double = x - 1.0
      Dim xp1 As Double = x + 1.0
      Dim xp2 As Double = x + 2.0



      If xp2 <= 0 Then
          a = 0
      Else
          a = xp2 * xp2 * xp2
      End If

      If xp1 <= 0 Then
          b = 0
      Else
          b = xp1 * xp1 * xp1
      End If

      If x <= 0 Then
          c = 0
      Else
          c = x * x * x
      End If

      If xm1 <= 0 Then
          d = 0
      Else
          d = xm1 * xm1 * xm1
      End If
     
      Return (0.16666666666666666 * (a - (4.0 * b) + (6.0 * c) - (4.0 * d)))

  End Function

There's one caveat though, I didn't do any Alpha premultiplication with this code, which basically means if your images have a non FULLY opaque region, the results won't be pretty. Here's your homework assignment if you want to have that functionality.

I learnt 2 things while porting this code.

  1. Don't use Math.Pow() if your code is time sensitive, ie. it needs to work REALLY REALLY fast. Like in a game render loop. Takes a bit longer to run math.pow(x,3) instead of x*x*x. Not saying you shouldn't use it, just don't use it when MILISECONDS matter.
  2. Visual Basic's IIF statement isn't good for performance as well since BOTH true and false statements seem to be evaluated and does execution time is wasted when execution time matters. Better to use the usual IF..ELSE..ENDIF construct.

After my little exercise in dabbling with this, THEN I find a WriteBitmapEx library which pretty much seems to be a very useful class for raw manipulation of images in Silverlight, check it out!

Friday, March 19, 2010 12:24:20 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Comments [0]  | 
# Thursday, February 18, 2010

So I’ve talked about Small Basic before, and they’ve just released a new version. So what’s so cool about this nice little tool for learning basic? Well it’s about how you can now show code to people. For example, let’s say I have a simple turtle program and while I can show you the code here.

start:
GraphicsWindow.Clear()
Turtle.MoveTo (0,0)
Turtle.MoveTo(GraphicsWindow.Width,0)
Turtle.MoveTo(0,GraphicsWindow.Height)
Turtle.MoveTo(GraphicsWindow.width,graphicswindow.Height)
Turtle.MoveTo(0,0)
Goto start

Then start explaining what the code does or… if you have already downloaded Small Basic, I could give you the Small Basic code of TRM169

Or… you can just SEE THE CODE IN ACTION with the brand new RUN IN SILVERLIGHT publishing capability and you can actually see how the code runs!

And that is just so farking cool! Unbelievably useful for showing people how code samples would work! Think there are still some bugs though, but not a bad start.

Thursday, February 18, 2010 8:50:55 PM (Malay Peninsula Standard Time, UTC+08:00)  #    Comments [0]  | 
# Tuesday, January 12, 2010

I was getting a few complaints that the websites we were working on stopped working on Google Chrome. Which came as a big surprise to me since when I repeated the test on my system and it worked properly. I managed to take a look at one of the users who was having problems and noticed that she was running the latest Chrome Beta with Extensions support. She had already installed a few extensions as well.

Acting on a hunch I disabled all extensions and... the website started working again.

Why was this happening? Well, the extensions/add-ons/plugins you've installed onto your browser (Doesn't matter if it's IE, Firefox or Chrome) have the capability of manipulating and analyzing the page you're viewing so they can do whatever it is they do. And when they DON'T do it properly, they start breaking the pages you're viewing by maybe.... inserting elements of their own, or changing tags and CSS class names of elements? In the age of AJAX where the webpages themselves are heavily running client side code to manipulate the document at the client end this could lead to disastrous results.

I guess the fact that extension support is technically still in Beta for Chrome also adds to the reasons for failure.

While these incidents with the extensions just reinforces my mindset that all web browsers are inherently stable until 3rd party plugins/add-ons/extensions are introduced. I worry about the day where a client will insist that there's a problem with a webpage because it doesn't work with their browser that has a particular extension/plugin/add-on installed.

So, if you had a webpage that was working fine previously before you added that new fangled Firefox Extension or Chrome Extension Or IE Add-On, maybe you might want to turn that particular thing off and try the page again?

Tuesday, January 12, 2010 10:23:29 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Comments [0]  | 
# Wednesday, September 09, 2009

Here's an important thing to take note of when making RIA applications. Wheter it's Flash, Silverlight or just plain AJAX. If you need to make a call through the browser's for data, always append a random query string parameter to it so the browser will never return to you a cached response! For example suppose your code calls this URL for data.

http://www.myapp.com/mypage.aspx?id=myid

After the first call to the page, it's likely that the browser might just cache the results and give you the same data for any following calls. Therefore you need to insert a random factor into the url like this.

http://www.myapp.com/mypage.aspx?id=myid&rnd={5656-234-3435}

It DOESN'T MATTER WHAT IT IS, it could be a number, current tickcount, guid, as long as it makes the browser think that it needs to hit the server and get a new page.

On the flip side, if you know your page will be hit via client side calls, it's a good idea to disable caching in the response headers.

Wednesday, September 09, 2009 10:56:31 PM (Malay Peninsula Standard Time, UTC+08:00)  #    Comments [2]  | 
# Sunday, March 29, 2009

I've finished my little proof of concept application that's using Windows Presentation Foundation. And I'm EXTREMELY pleased with the results, performance under Windows XP feels just the same and I guess it should be better once I actually optimize the handling of media.

All in all, while I was once afraid and skeptical about using WPF as a platform for writing Windows Client applications making the POC has changed that mindset for me. And now I'm glad I have WPF as a tool in my belt.

Though I wish they'd make it easier to hide the darn text input caret for the RichTextBox! Had to go through an ugly ugly hack just to do that!

Sunday, March 29, 2009 2:02:53 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Comments [0]  | 
# Monday, March 16, 2009

MS is trying to host a online conference called Tech Days for developers on 1st April 2009. Seems like it's going to provide all the benefits of a typical MS conference, minus the commuting. The date is.... interesting though, the joke would be on us if our internets crap out on that day.

Monday, March 16, 2009 11:34:51 PM (Malay Peninsula Standard Time, UTC+08:00)  #    Comments [0]  | 
# Friday, March 13, 2009

The last time I attempted WPF I was a bit put off by the new programming model, and also the fact that performance could have been better. But then again... it could just be my machine, so.... after a reformat I'm ready to try again. Also, I have some XAML experience under my belt via my adventures with Silverlight so let's see how well it works out for me this time.

Friday, March 13, 2009 12:55:33 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Comments [0]  | 
# Monday, February 02, 2009

For my own reference, in order to call an MTOM encoded web service from .Net 3.5 client I need to stick the following in the custombinding section

<binding name="MyServiceHttpbinding" messageEncoding="Mtom">
         <mtomMessageEncoding messageVersion ="Soap12"  ></mtomMessageEncoding>     <httpTransport/>
        </binding>

Monday, February 02, 2009 10:10:48 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Comments [0]  | 
# Thursday, January 08, 2009

An XML Schema is a contract you don’t change it whenever you feel like it without telling people. And if you still don’t understand the rules of XML, like being case sensitive… only have one root node.

GO GOOGLE IT!!!!

FUCK!

Thursday, January 08, 2009 5:04:40 PM (Malay Peninsula Standard Time, UTC+08:00)  #    Comments [1]  | 
# Tuesday, December 16, 2008

So the new year is coming and what better way to start the year than by learning something new? There’s a Technet MSDN technology summit that’ll be happening on 15th January 2009 over at the KL Convention center. And there’ll be demos of the MS Virtualization platform, and more interesting to me would be that there’ll be sessions on AZURE, yum yum indeed.

Oh there’ll also be a demo of Windows 7 for those of you who like me haven’t bothered to acquire the preview released during PDC.

And maybe… just maybe.. and this is just ME saying this.

We *might* actually get a new Beta of Windows 7.

Just remember.. operative word here is *MIGHT*… with asterisks too!

Tuesday, December 16, 2008 10:15:38 PM (Malay Peninsula Standard Time, UTC+08:00)  #    Comments [0]  | 
Page 1 of 8 in the Programming category Next Page