Tuesday, January 19, 2010

Cheap Mini Photo Portable Studio

I had several hours of free time during the Christmas holiday and I grabbed my camera and experimented on how to make a small item shot that looks decent, with a small/no budget. This exercise is pretty useful in real life if you are someone who put a lot of stuff on Ebay or online listing (ie. craigslist, etc).

The goal is to be portable, cheap, and quick - but also produces nicely lit object. I want a fairly soft light to create a nice even light. So, I am thinking either bounced light or diffused light. I went with diffused light, since it is easier to control the power that way.

So here are items that I used, which most if not all you can find in your house or buy cheaply:

  • Parchment paper or wax paper. This is for the diffuser.
  • Open cardboard box for creating a boxed controlled environment, cut out to attach the parchment paper (see setup shot for an example).
  • A black or dark surface. Or glass/reflective surface will also work.
  • A piece of blank white paper/carton to be a reflector.

I happen to have a black dining table that is a fairly smooth surface - so I used that as my surface. I put my box above the object, with another cut-out hole on the top of the box to let the light go through.

I setup my flash about 2-3 ft above the box facing down into the box. Attach the parchment paper on the cut-out hole to diffuse the light. Place the paper reflector inside the box on the other side of where the flash is.

Setup up the max sync speed on your camera and adjust your aperture to get a complete darkness exposure - this is for making sure that your only source light is your flash, not the dining room lamp, the sun, etc etc. Now turn on your flash and adjust the power of your flash to get a good exposure. Tweak the distance between your flash and the box as necessary, or add another layer of parchment paper if needed.

Here is my setup shot:




Learn How To Light via Strobist
Overpowering The Ambient

-- read more and comment ...

Monday, January 4, 2010

Some funny stuff on the web ...

There are some things on the web that you just have to bookmark ... and share. Here are some that I found in 2009 that I think are funny (or outrageous) enough to bookmark and share:

http://thereifixedit.com
How to fix the problem in our lives with extra-ordinary creativity, extremely cheap, works, and at the end of the day you can say "There! I fixed it!"

http://www.notalwaysright.com
For the record: Customer is NOT Always Right!

http://www.dontevenreply.com
Have you ever posted something in Craigslist? .... And got replies from hell? Apparently a lot of people have.

http://www.peopleofwalmart.com
Walmart is really my favorite place ... this site is a testimony of it.

http://thedailywtf.com/
Yes, they update it daily, because WTF moments happen daily!

http://xkcd.com/
The MODERN Far Side!

http://awkwardfamilyphotos.com/
The URL says it all ... awkward indeed!

I will add some more as I remember them ... so far, that's all.

-- read more and comment ...

Monday, December 14, 2009

Poop Ethiquete at Work

This post is NOT originally mine - I got it from the internet like here and here.

We've all been there but don't like to admit it. We've all kicked back in our cubicles and suddenly felt something brewing down below. As much as we try to convince ourselves otherwise, the WORK POOP is inevitable.

For those who hate pooping at work, following is the Survival Guide for taking a dump at work.

CROP DUSTING
When farting, you walk briskly around the office so the smell is not in your area and everyone else gets a whiff but does not know where it came from. Be careful when you do this. Do not stop until the full fart has been expelled. Walk an extra 30 feet to make sure the smell has left your pants.

FLY BY
The act of scouting out a bathroom before pooping. Walk in and check for other poopers. If there are others in the bathroom, leave and come back again. Be careful not to become a FREQUENT FLYER. People may become suspicious if they catch you constantly going into the bathroom.

ESCAPEE
A fart that slips out while taking a leak at the urinal or forcing a poop in a stall. This is usually accompanied by a sudden wave of embarrassment. If you release an escapee, do not acknowledge it. Pretend it did not happen. If you are standing next to the farter in the urinal, pretend you did not hear it. No one likes an escapee. It is uncomfortable for all involved. Making a joke or laughing makes both parties feel uneasy.

JAILBREAK
When forcing a poop, several farts slip out at a machine gun pace. This is usually a side effect of diarrhea or a hangover. If this should happen, do not panic. Remain in the stall until everyone has left the bathroom to spare everyone the awkwardness of what just occurred.

COURTESY FLUSH
The act of flushing the toilet the instant the poop hits the water. This reduces the amount of air time the poop has to stink up the bathroom. This can help you avoid being caught doing the WALK OF SHAME.

WALK OF SHAME
Walking from the stall, to the sink, to the door after you have just stunk up the bathroom. This can be a very uncomfortable moment if someone walks in and busts you. As with farts, it is best to pretend that the smell does not exist. Can be avoided with the use of the COURTESY FLUSH.

OUT OF THE CLOSET POOPER
A colleague who poops at work and is damn proud of it. You will often see an Out Of The Closet Pooper enter the bathroom with a newspaper or magazine under their arm. Always look around the office for the Out Of The Closet Pooper before entering the bathroom.

THE POOPING FRIENDS NETWORK (P.F.N)
A group of co-workers who band together to ensure emergency pooping goes off without incident. This group can help you to monitor the where about of Out Of The Closet Poopers, and identify SAFE HAVENS.

SAFE HAVENS
A seldom used bathroom somewhere in the building where you can least expect visitors. Try floors that are predominantly of the opposite sex. This will reduce the odds of a pooper of your sex entering the bathroom.

TURD BURGLAR
Someone who does not realize that you are in the stall and tries to force the door open. This is one of the most shocking and vulnerable moments that can occur when taking a poop at work. If this occurs, remain in the stall until the Turd Burglar leaves. This way you will avoid all uncomfortable eye contact.

CAMO-COUGH
A phony cough that alerts all new entrants into the bathroom that you are in a stall. This can be used to cover-up a WATERMELON, or to alert potential Turd Burglars. Very effective when used in conjunction with an ASTAIRE.

ASTAIRE
A subtle toe-tap that is used to alert potential Turd Burglars that you are occupying a stall. This will remove all doubt that the stall is occupied. If you hear an Astaire, leave the bathroom immediately so the pooper can poop in peace.

WATERMELON
A poop that creates a loud splash when hitting the toilet water. This is also an embarrassing incident. If you feel a Watermelon coming on, create a diversion. See CAMO-COUGH.

HAVANA OMELET
A case of diarrhea that creates a series of loud splashes in the toilet water. Often accompanied by an Escapee. Try using a Camo-Cough with an ASTAIRE.

UNCLE TED
A bathroom user who seems to linger around forever. Could spend extended lengths of time in front of the mirror or sitting on the pot. An Uncle Ted makes it difficult to relax while on the crapper, as you should always wait to poop when the bathroom is empty. This benefits you as well as the other bathroom attendees.

-- read more and comment ...

Friday, December 4, 2009

Ooma Review

In August, I bought a phone gadget called Ooma. You can go to their website to get a full exposure of what it is etc here. For me, I am using it for money saving cost for international calls between my parents and my family in US. We talk pretty frequently and I have been paying around $20-ish per month for long-distance international calls on my land line. So in a year, I amp paying around $300 for international calls and that's just me. If my mom calls me from Indonesia, I don't pay anything but she pays her international charge from her phone carrier.

Prior to this, I was considering other options such as Skype, Vonage (or any other VoIP solutions), MSN/YM web-cam chats, etc - but nothing seems to work as good as Ooma as a whole experience.

So, if you are calling internationally a lot and want to save some money, you may want to consider Ooma. Read my experience with it and why is it my solution of choice after the jump.

REQUIREMENT
You will need a broadband connection for Ooma to be able to works as expected. The connection speed where I hooked up my Ooma with is pretty modest (768dl and 256ul), but so far it works pretty well as soon as the internet is not used up for heavy downloading.

COST
Ooma will cost you around $200 up-front. Unlike Vonage or other VoIP solutions, which are using subscription model, Ooma actually sells you a device AND you do NOT need to pay anything else. You have the option to add more advance options stuff if you want (and you do have to pay for them) - but I don't need them - so I only pay $200 for the device and that's it. So right of the bat, Ooma is a CHEAPER solution in the long run compared to Vonage ($15 / mo).

INTERNATIONAL CALLS
But Ooma's website says it will charge you if you are calling internationally? Yes, that is right. What I did:

  1. Registered my Ooma under my name
  2. Gave it a local number (so area code is the same as my home phone, my cell, my wife's cell, and my office number)
  3. Setup the device at my home (very easy) and test it for several hours (or days if you want)
  4. Send the device to my parents and tell them how to hook it up with their broadband internet router
  5. Plug a cordless phone to the device.
This setup enables me to call my parents anytime without incurring international calling cost. If I call them from my home phone, it is FREE. If I call from my cell phone, I only lose my cell-minutes. If I call from the office phone, it's FREE. And ... they also can call me anytime for FREE.

    PHONE / AUDIO EXPERIENCE
    My experience with Ooma as a far as audio quality has been great. Only a few times that my mom would call me and the sound quality were like broken up - those were caused by my dad/brother downloading MS updates/photos/music from the internet. Once they stopped the download and recalled, quality back to clear and no delay. It is basically as good as calling from a land-line to another land-line locally; clear, no delay, and full duplex quality.

    WEB-CAM/SKYPE?
    Webcam/Skype kind of requires you to sit in front of a computer. To hook it up to a regular phone, you have to buy an extra device to connect and then maintaining the software, etc. I am ok with all that, but I don't think my parents is quite a tech-savvy to able to handle all that. Ooma is a stand-alone hardware, plug and play. No software, no computer, just plug into the router, connect your own phone, and voila!

    All in all, after 4 months of usage - I am very satisfied with Ooma and recommend you to use it if you have the need for frequent long distance calling like me.
    -- read more and comment ...

    Thursday, September 10, 2009

    SQL Shortcut Tip

    In creating a SQL select statement to query some records from a table, it is pretty common to include WHERE clause - where you are limiting your selections by criterias specified.

    Here is an example:

    SELECT *
    FROM Products
    WHERE CategoryID = 5
    The SQL statement above will return all Product records that are in Category 5.

    Now, sometimes we want to use the condition only if it meets certain condition (like if the condition value is not empty or null).

    So you SQL statement may look like this (assuming this is wrapped in a stored procedure) - where you want the stored procedure to return all Products if Category is not filtered:
    ALTER PROCEDURE [dbo].[GetProducts] 
    @CategoryID int = NULL 
    AS
    
    IF (@CategoryID IS NULL)
    BEGIN   
    SELECT *   
    FROM dbo.Products
    END
    ELSE
    BEGIN   
    SELECT *   
    FROM dbo.Products   
    WHERE CategoryID = @CategoryID 
    END  
    Looks rather long isn't it? In LINQ this is a bit shorter, but still quite repetitive:
    var data;
    if (categoryId == 0)
       data = from row in db.Productselse
       data = from row in db.Products where CategoryID == categoryId 
    So how can we short-cut this into shorter statements that is elegant and still do the job well?
    Like this:
    ALTER PROCEDURE [dbo].[GetProducts]
      @CategoryID int = NULL
    AS   
    
    SELECT *   
    FROM dbo.Products   
    WHERE (@CategoryID is NULL OR @CategoryID = 0) OR CategoryID = @CategoryID 
    In LINQ:
    var data = from row in db.Products
               where (CategoryID == categoryId  || categoryId == 0)
    By including the possibility of null or zero (or any default condition) in the WHERE clause means that the condition will be computed as well to produce the results. Got it?
    -- read more and comment ...

    Wednesday, August 26, 2009

    Dirty Franks!

    A friend of mine told me about this "hot dog" place called "Dirty Franks" - so in the name of trying new restaurant, we went. Here are some information about Dirty Franks:

    Website: http://www.dirtyfrankscolumbus.com/
    Twitter: http://twitter.com/dirtyfranksdogs

    248 South 4th Street
    Columbus, Ohio 43215
    614.824.4673
    Hours: 11am to 2:30am

    Food:
    I think their food is great. Their menu is basically hot dogs with different styles. You can get Chicago style hot dog, hot dog with kim chee, with beans, topped with brisket, or anyway you want it (called "Your Wiener"). See their full menu here. You can substitute the franks with Polish sausage, brats, veggie sausage, etc. I have tried several of them and I like "Dog From Hell" and "Chicago" the most (out of the seven or so).

    Drinks:
    They have a full bar - which is nice. But, the stuff to get is the Slushes or Root Beer Floats. They use the local Jenis ice cream for their floats - which is awesome.

    Price:
    Relatively cheap - $3 per hot dog. So if you are only after 1 dog, side and drink water, it will cost you $5-ish. I ordered 2 dogs, a side, and pop - set me back around $10 - and went home super full.

    Atmosphere and Service:
    The place is kinda small and packed during lunch hours. So if you are planning to come for lunch, come early (like before 11:30) or late. For dinner, it is still packed, but not as bad. Decoration is kinda funky/artsy - which is - depending on your taste - could be weird or cool. I personally like it. Service is superb, my drink is never empty, meal is fast, and my server is friendly.

    So, check them out!
    -- read more and comment ...

    Sunday, August 23, 2009

    How to hide/show Table Rows with jQuery

    With jQuery, hiding and showing DOM elements are easy. But, one thing that I find a little bit challenging is hiding table row(s). Hiding and showing DIVs are easy:

    function togglePanel(id) {
    var viewContainer = $(id);
    viewContainer.slideToggle("normal");
    }
    

    Or you can use show() and hide() or fadeIn() and fadeOut(). With our corresponding HTML:
    <a href="javascript:togglePanel('#myDiv')">Toggle</a>
    <div id="myDiv">Hello World</div>
    


    Now what if we are using TABLE instead of DIV??

    Easy - Use TBODY tag. Here is an example using TABLE:
    <table id=anothersortable>
    <tbody id=row01 class=content>
    <tr><td>one</td></tr>
    </tbody>
    <tbody id=row02 class=content>
    <tr><td>two</td></tr>
    </tbody>
    </table>
    <a href="javascript:togglePanelMore('#row01', '#togglerow01')"      id="togglerow01">less</a> for row01
    

    Then our jQuery to be as such:
    function togglePanelMore(id, source) {
    var viewContainer = $(id);
    
    if ($(source).html() == "more") {
    $(source).html("less");
    viewContainer.show();
    }
    else {
    $(source).html("more");
    viewContainer.hide();
    }
    }
    

    IE 7 Quirks
    In IE 8, you can refer to the TR directly without TBODY, like this:
    <table id=anothersortable>
    <tr id=row01><td>one</td></tr>
    <tr id=row01><td>two</td></tr>
    </table>
    <a href="javascript:togglePanelMore('#row01', '#togglerow01')"
    id="togglerow01">less</a> for row01
    
    But for some reason, it is not reliably working in IE7.

    Also, in IE7, putting speed inside the hide()/show() into becoming like hide('slow') won't work.

    Here is a small demo.
    -- read more and comment ...

    Sunday, July 12, 2009

    Adding SyntaxtHighlighter javascript with Blogger

    Ever heard of "Syntax Highlighter"? This is the javascript framework that converts all the plain text code in my blog (and many other blogs, like Scott Hanselman's) into a neat and highlighted code segments with line number etc - almost like looking at it in an IDE.

    You can review, download, and get the main instructions here.

    This post is about how to use it with Blogger, Google's blogging engine. Which includes steps in modifying the blogger template of your choosing.

    1. After logging in to you blogger account, go to "Layout" and "Edit HTML" tab. You should see a screen like this:

    2. Copy the url of the hosted files from http://alexgorbatchev.com/pub/sh/current/ for both styles and scripts for ones you want to use and link them as CSS and javascript include in your template, right below the "HEAD" tag. Like this (or you can copy these lines below if you want):

      <link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/>
      <link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>
      <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'/>

      <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js' type='text/javascript'/>
      <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCSharp.js' type='text/javascript'/>
      <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCss.js' type='text/javascript'/>
      <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' type='text/javascript'/>
      <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js' type='text/javascript'/>
      <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushSql.js' type='text/javascript'/>
      <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'/>
      <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shLegacy.js' type='text/javascript'/>


    3. Then scroll all the way down to the bottom of your template, until you see the comment marking for "end-outer-wrapper" and before the closing "body" tag. Here you will need to initialize the Syntax Highlighter by executing several javascript lines. If this is the first time you've used Syntax Highlighter, you probably won't need the last line ("dp.SyntaxHighlighter ..."), since it is really code to enforce backward compatibility with previous version of Syntax Highlighter marking.

      <script language='javascript'>
      SyntaxHighlighter.config.bloggerMode = true;
      SyntaxHighlighter.all();
      dp.SyntaxHighlighter.HighlightAll('code');
      </script>


    So now, how do you use it? It's pretty easy. Read here for for the usage/user's guide. In essence, you will just need to surround your "code" with a "pre" tag and depending on what coding language your code is, you will need to assign certain values to the "pre" tag's attribute. Here are some examples:

    // for HTML/XML
    <pre class="brush:html">
    <UL id=sortable>
    <li>one</li>
    <li>two</li>
    <li>three</li>
    <li>four</li>
    </ul>
    </pre>

    // for javascript
    <pre class="brush:js">
    alert("Hello world");
    </pre>

    // for C#
    <pre class="brush:c#">void dfShipper_DeletingItem(object sender, System.ComponentModel.CancelEventArgs e)
    {
    northwindDSContext.DeleteObject(dfShipper.CurrentItem);
    northwindDSContext.BeginSaveChanges((asyncResult) =>
    { northwindDSContext.EndSaveChanges(asyncResult); }, null);
    }
    </pre>

    -- read more and comment ...

    Wednesday, June 17, 2009

    Twitter via Mobile Devices

    You're on Twitter and use a mobile device? Here is a list of mobile device applications (obviously not exhaustive) that will hook you up to Twitter:

    Windows Mobile:
    Twikini
    ceTwit
    TwitToday

    Blackberry:

    Twitterberry
    Blackbird
    Twibble

    iPhone (get from iTunes):
    TweetDeck for iPhone
    Tweetie
    Twitterific
    Twinkle

    You can follow me on Twitter: http://www.twitter.com/setiabud -- read more and comment ...

    Monday, June 8, 2009

    jQuery UI Sortable with TABLE

    Drag and drop sorting on a web application? This thought is so far fetched several years ago - and now everybody is or can do that easily with jQuery. Looking at the tutorials and documentation in jQuery's website, it lays out a simple method to call to make our list to become sortable.

         $(function() {
            $("#sortable").sortable();
            $("#sortable").disableSelection();
        });
    With our corresponding HTML:
         <ul id=sortable>
            <li>one</li>
            <li>two</li>
            <li>three</li>
            <li>four</li>
        </ul>
    
    Here is a demo on how that works.
    Now what if we are using TABLE instead of UL or OL??Easy - Use TBODY tag. So using the example above, let's convert the list into a table:
         <table id=anothersortable>
            <tbody class=content> 
                <tr><td>one</td></tr>
                <tr><td>two</td></tr>
                <tr><td>three</td></tr>
                <tr><td>four</td></tr>
            </tbody>
        </table>
    Then our jQuery to be as such:
         $(function() {
            $("#anothersortable tbody.content").sortable();
            $("#anothersortable tbody.content").disableSelection();
        });
    Click for demo for the simple table.You can even make this having sub-sort - or with children sorting. Like this:
         <table id=subsortsortable>
            <tbody class=content>
                <tr><td>one</td></tr>
                <tr><td>two</td></tr>
                <tr><td>
                    <table><tbody class=subcontent>
                        <tr><td>three.one</td></tr>
                        <tr><td>three.two</td></tr>
                    </tbody></table>
                </td></tr>
                <tr><td>four</td></tr>
            </tbody>
        </table>
    
    Adjust our jQuery to be as such:
         $(function() {
            $("#subsortsortable tbody.content").sortable();
            $("#subsortsortable tbody.content").disableSelection();
            $("tbody.subcontent").sortable();
            $("tbody.subcontent").disableSelection();
        });
    
    Click for demo of this one. UPDATE: Viewer Coolboy in his comment below pointed out that viewing in IE7 may sometimes introduce unexpected behavior in the y axis. I can replicate the problem and have found a solution or a work around for it by using "handler". Using handler, you basically designating a "dragging" point, instead of using the whole row as to drag. So in using handler, our code changes a little bit in both HTML and javascript. Here is the updated HTML:
         <table id=subsortsortable>
            <tbody class=content>
                <tr><td><label class="levelonehandle">X</label></td><td>one</td></tr>
                <tr><td><label class="levelonehandle">X</label></td><td>two</td></tr>
                <tr><td><label class="levelonehandle">X</label></td><td>
                    <table><tbody class=subcontent>
                        <tr><td><label class="leveltwohandle">X</label></td><td>three.one</td></tr>
                        <tr><td><label class="leveltwohandle">X</label></td><td>three.two</td></tr>
                    </tbody></table>
                </td></tr>
                <tr><td><label class="levelonehandle">X</label></td><td>four</td></tr>        </tbody>
        </table>
    
    Then our javascript as such:
         $(function() {
            $("#subsortsortable tbody.content").sortable({
                    handle: ".levelonehandle"
                });
            $("#subsortsortable tbody.content").disableSelection();
            $("tbody.subcontent").sortable({
                    handle: ".leveltwohandle"
                });
            $("tbody.subcontent").disableSelection();
        });
    
    -- read more and comment ...

    Wednesday, June 3, 2009

    How to Do Sharpening in Photoshop

    Why do we need "sharpening"? Well, you actually don't. But, given 2 identical photos, you will see that the one that is sharpened will be able to identify that it seems to be better focused and "sharp". This, a lot of times enhance the photographic viewing experience and create a more detailed perception of the picture.

    Let's look at an example:
    Original photo (cropped)


    Here is the same image after sharpening (and color correction)
    Pay attention to the pointy tip of the flower and the creases - and you can see a lot more if you view large (by clicking on the images).

    The sharpening technique I used is called "edge sharpening". There are a lot of variety and settings that people use for this kind of sharpening (click here for Google search result for "edge sharpening"). There are other types of sharpening, lab-sharpening or just plainly using the unsharp mask. I am not going to discuss those methods in this post, but only going to focus on edge-sharpening.

    Here is the step-by-step process that I usually take (you can make this into an action if you want) - I am using Photoshop CS and I am assuming that it will be similar in the newer versions:


    1. Open you image, crop, adjust levels, curve, etc etc.
    2. Create a new channel: Go to channel palette, click the new channel icon on the bottom. Put a name on your channel, call it "Sharp Channel" (or whatever you want). In PS CS, it will create a new channel and focus on this new channel (black screen/image). Still on the channel palette, click on the RGB channel to focus back on your image.
    3. Select the whole image (Ctrl-A or do SELECT - ALL), and then copy the whole image (EDIT - COPY or EDIT - COPY MERGE)
    4. Paste it on the new channel "Sharp Channel": select the "Sharp Channel" and then paste (EDIT - PASTE). It will display as black and white, which is OK.
    5. Find edges: Make sure the "Sharp Channel" is focused/selected, and then click FILTER - STYLIZE - FIND EDGES
    6. Eventually we are going to make this as a mask. So that means that the black part will affect your image and the white area won't. If you are pretty satisfied with the mask (it is hard to say what is a "good" one at this point - you will just have to experiment), you can skip step 7 and go to step 9 directly. I usually (9 out of 10) always do step 7 & 8 ...
    7. Click IMAGE - ADJUSTMENTS - LEVELS. Try to adjust the levels by moving the triangular slide below the histogram. You basically want to make black to be very black and white to be white. Keep in mind that once we convert this channel into a mask, the black area are the one that will be sharpened. Play with this (unfortunately with trial and error) until you get the desired effect.
    8. If there are details, lots of lines, etc, you may want to introduce a nice smoot transition from the sharpened area to the non-sharpened area. Use Gaussian Blur to do this: FILTER - BLUR - GAUSSIAN BLUR (enter between 1-5 px).
    9. Now click SELECT - LOAD SELECTION. A dialog box will show up and make sure the selected channel is correct and "INVERT" checkbox is checked. Hit OK.
    10. Click "Layers" (you were on "Channels"). The mask from our edge will be super-imposed on our image. You can hide this "blinking selection" by doing this: click VIEW - SHOW - and uncheck SHOW SELECTION.
    11. Now we are ready for sharpening. It is usually helpful to view the image in large view/zoomed in. I would go for 100% zoom/view before start sharpening - so I can see/preview the affect of the sharpening. Click FILTER - SHARPEN - UNSHARP MASK. Try out combination of values in the USM window until you get the desired result. I recommend to keep the threshold to 0 and the radius to be less than 1.5.
    There you go - good luck!
    -- read more and comment ...

    Friday, May 29, 2009

    URLRewritter & .NET 3.5 SP1

    In one of our project, we encountered this error when we pushed our code to the server:

    Validation of viewstate MAC failed. If this application is hosted by a Web Farm or cluster, ensure that configuration specifies the same validationKey and validation algorithm. AutoGenerate cannot be used in a cluster.

    Our web server is a stand alone server, not a cluster/web-farm. So after digging around, there are multiple issues that related to our problem that can ultimately cause this error to show up:
    1. From here: WebForm starts paying attention to the "action" attribute of the form tag in .NET 3.5 SP 1. So, if they are unmatched, this error will be generated.
    2. We use URLRewritter, in which means that our URL in the location bar is different (modified) than the one in the action attribute.
    3. In IIS7 or VS 2008 emulator, this problem cannot be replicated

    There are also other issues that can cause this error (but they are not related to my project - and you can read about them here and here.

    So, how did I solve my problem? I can just simply upgrade my web server to IIS7, but that was not an option when I was working on this. Here are the things that I did:
    1. Add event handler to blank out the form action from global.asax.vb file for each request (read here)
    2. Change form tag into the one supplied by URL Rewritter (read here)

    Those 2 steps provide me with a URL that is identical in my action attribute on the form as well a consistent URL - which mean ViewState is valid!
    -- read more and comment ...

    Thursday, May 28, 2009

    Cascading Drop Down with ASP.NET MVC, jQuery with JSON

    Cascading drop down is webform is pretty easy by using postback - or UpdatePanel. In MVC, how would it be done? jQuery comes to the rescue for this problem. Since ASP.NET MVC is able to return a JSON format result, what we need to do then is just calling that Controller's Action via jQuery and then display the drop down. Let's use an example:Say I want to list available counties per state. So the the first drop down will be the state drop down, and based on the selection of the state, the second drop down will display available counties for the selected state.

    Here is a snippet of the HTML for our two drop downs, for both states and counties.
     
    <%= Html.DropDownList("StateID", Model.StateList) %>
    <select name="CountyID" id="CountyID"></select>
    
    So since we need to (re)populate the county drop down for each selection/change of the StateID drop down, we use the .change method in jQuery.
     
    $(document).ready(function() {
        $("#StateID").change(function() {    });
    });
    
    First, we need to get the selected State and also make sure that the default State selection will also execute and display the list of Counties appropriately.
     
    $(document).ready(function() {
        $("#StateID").change(function() {
            var strStateID = "";
            strStateID = $(this)[0].value; // get the selected state id
        })
        .change(); // making sure the event runs on initialization for default value
    });
    Once we have the state id, we can then call our controller's action to get a list of counties back via AJAX.
     
    $(document).ready(function() {
        $("#StateID").change(function() {
            var strStateID = "";
            strStateID = $(this)[0].value; // get the selected state id
            var url = "/MyController/Counties/" + strStateID;
            // call controller's action
            $.getJSON(url, null, function(data) {
                // do something once the data is retrieved
            });
        })
        .change(); // making sure the event runs on initialization for default value
    });
    With the data in hand, we can (re)build the County drop down with the values returned from the controller.
     
    $(document).ready(function() {
        $("#StateID").change(function() {
            var strStateID = "";
            strStateID = $(this)[0].value; // get the selected state id
            var url = "/MyController/Counties/" + strStateID;
            // call controller's action
            $.getJSON(url, null, function(data) {
                // do something once the data is retrieved
                $("#CountyID").empty();
                $.each(data, function(index, optionData) {
                    $("#CountyID").append("<option value='"
                         + optionData.CountyID
                         + "'>" + optionData.CountyName
                         + "</option>");
                });
            });
        })
        .change(); // making sure the event runs on initialization for default value});
    -- read more and comment ...

    Wednesday, May 6, 2009

    VMWare Server 2.0 Troubleshooting

    Yesterday, my VMWare Server stops working. It did not give me the login screen - so I thought maybe I just need to restart the host agent service under Services. I wrote a post about this here.

    So I went to Services, found that the host agent is stopped and I restarted it. Then I got this error:



    Aaaarrrrgggh!!! So anyway - I went around, googled it, read the logs, etc etc, and resolved it.

    In my case the error was cause by a malformed XML file for VMWare configuration. The XML in my Win XP host is located at "C:\Documents and Settings\All Users\Application Data\VMware\VMware Server\hostd".

    I am guessing that when I installed VMWare, I probably chose "allow all users to use it" - and if you picked "allow only me", the xml files probably will reside under your username instead of under "all users".

    So what I did was just opening the XML file one by one with an XML editor (I used Visual Studio) until I found the culprit XML file - which in my case was the datastores.xml - then fixed the tags and save.

    Then via Services, I restarted the host agent service.


    Voila! It works!
    -- read more and comment ...

    Saturday, May 2, 2009

    Investing on Cameras or Lenses?

    Every year, there are several DSLRs coming out with new features and functionality that are eclipsing the past years DSLRs. If your have a DSLR and it was from several years ago, you may feel that it is quite obsolete compared to the new ones coming out this year. They are cheaper too!

    To illustrate the point, let's say you have a entry level DSLR from Nikon, the Nikon D40 - which is release on December 2006. So a two and a half year old camera. It has big bright 2.5 inches screen, small, 3 focus points, 2 frames per seconds, built in flash, info view, scene modes, etc - for $549. It was the best selling DSLR at some point, the biggest bang for the buck.

    So what would you do? Get a new DSLR every year (or every other year)? Or maybe lenses?

    I recommend getting several flashes and some light stand and learn how to light via Strobist! Financially, it saves you LOTS of money (spend hundreds instead of thousands of dollars) AND exponentially improve your photographic skill - even with your current camera and lenses!

    Now why is that? Or how does it work? Strobist provides tons of "how-to" etc (take lighting 101) and lighting resources (where to buy, reviews, etc). Secondly, most people usually want to get newer lenses because they need "faster" lenses. Faster lens means larger opening to capture more light. The standard kit lens is usually a "slow" lens, where it does not have the ability to capture light as fast as the faster lens. So, lighting/flashes compensate that by adding more light! So if you learn how to light - it will make your equipment to be more useful and all the more, you can do a LOT of things that really not possible without flashes.

    Consider also this cost analysis:
    Getting a new fast lens probably cost you $1,500. Getting an SB-800 and 2 more SB-600 (so 3 flashes total) will cost you $~700. Throw in a pair or light stand, 2 umbrellas, some gels - ~$200 - brings up the total to $900 - that using Nikon brand, and some nicer brands of stands and umbrellas, etc. So, learn how to light: WORTH IT!!

    Now, if the choice is between camera and lenses, then I recommend in investing on lenses instead of camera. Several reasons:

    • All technique aside, it is the lens that contributes more into the sharpness of your picture
    • Beautiful bokeh (rendering of out of focus area) is caused by lens characteristics, not camera
    • Lens holds its value really well, unlike camera
    • Lens controls the aperture - which allow you to produce DoF, bokeh, and shutter speed - and of course the camera control the lens
    • Less need for upgrade for lenses
    • Studying the correct usage of lenses and its characteristics can improve your photographic skills better than camera
    So got an older camera and itching for an upgrade? I say hold it. Check out your lens arsenal, and improve them first. In most cases for amateur or serious amateur, what your camera can do is more than enough for our needs. So as long as your camera is compatible with the lenses, stick with it and get a NICE lens instead. Does this mean you should throw away your kit lens? Nah, not really. You can keep it around for most occasions - parties, trips, vacations, etc - where you just want to enjoy the moment instead of being hassled by taking photos and their settings.

    So, what do you currently have in your lens line up? I wrote a blog post about this in the past.

    I am still using my Nikon D80 and a Nikon film camera - and I am not anticipating for a camera upgrade anytime soon. They are both still do their jobs very very well. But since then, I have upgraded my lens line up to be as such:
    • AF-S 17-35 f/2.8
    • AF-S 24-70 f/2.8
    • AF-S 70-200 f/2.8
    BUT, again - my best investment so far are:
    • 2 Bogen Light Stands
    • 2 SB 600s
    • 1 SB 800
    • 1 SB 80DX
    • 2 White Umbrellas
    • 1 Silver Umbrella
    • 1 Multicolor reflector
    • 1 Set of gels
    With some of those lighting gear, I made this picture in this post.
    -- read more and comment ...