Click here to Skip to main content
Licence CPOL
First Posted 28 Feb 2008
Views 40,740
Downloads 1,170
Bookmarked 59 times

Image Glass Table Effect (Reflection) Using GDI+

By | 28 Feb 2008 | Article
This article introduces a simple algorithm to do a glass table effect using GDI+.

GlassTableGDI_src

Introduction

Recently, while writing an e-commerce web application, I needed to transform the product’s images in some “professional” way, so I decided to add to each product image a well known glass effect table. Since I’m broke, I can’t afford having an artist to modify each image, so I decided to write some simple algorithm to do it automatically using GDI+.

This article is more like a code snippet, for you who want do the same in your applications or websites. It’s simple, yet useful!

Using the code

To transform the image, simply use the static method of the helper, like this:

Image newImage = ImageEffectsHelper.DrawReflection(pOriginal.Image, Color.White, 90);

The parameters of this method are quite self-explanatory, but still, here they are:

  • Image – It’s the original image you want to make the reflection of.
  • BackgroundColor – The background color of the image, used to paint the reflection by using a gradient brush.
  • Reflectivity – From 0 to 255, it’s the reflectivity of the image (gradient brush alpha).

Example

I prepared a small example project, containing two Windows forms, so you will be able to select the image you want to process and preview the processed image.

original.png

Algorithm

Now, the algorithm itself; it calculates the height of the new image based on the desired Reflectivity. After that, it creates a new graphics buffer, draws the original image on it, and on a second graphics buffer, it draws the reflected image, then flips it. At the end, it simply merges both the images and uses a gradient brush (with the given alpha and BackgroundColor) on it. Here’s the code:

public static Image DrawReflection(Image _Image, Color _BackgroundColor, int _Reflectivity)
{
    // Calculate the size of the new image
    int height = (int)(_Image.Height + (_Image.Height * ((float)_Reflectivity / 255)));
    Bitmap newImage = new Bitmap(_Image.Width, height, PixelFormat.Format24bppRgb);
    newImage.SetResolution(_Image.HorizontalResolution, _Image.VerticalResolution);

    using (Graphics graphics = Graphics.FromImage(newImage))
    {
        // Initialize main graphics buffer
        graphics.Clear(_BackgroundColor);
        graphics.DrawImage(_Image, new Point(0, 0));
        graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
        Rectangle destinationRectangle = new Rectangle(0, _Image.Size.Height, 
                                         _Image.Size.Width, _Image.Size.Height);

        // Prepare the reflected image
        int reflectionHeight = (_Image.Height * _Reflectivity) / 255;
        Image reflectedImage = new Bitmap(_Image.Width, reflectionHeight);

        // Draw just the reflection on a second graphics buffer
        using (Graphics gReflection = Graphics.FromImage(reflectedImage))
        {
            gReflection.DrawImage(_Image, 
               new Rectangle(0, 0, reflectedImage.Width, reflectedImage.Height),
               0, _Image.Height - reflectedImage.Height, reflectedImage.Width, 
               reflectedImage.Height, GraphicsUnit.Pixel);
        }
        reflectedImage.RotateFlip(RotateFlipType.RotateNoneFlipY);
        Rectangle imageRectangle = 
            new Rectangle(destinationRectangle.X, destinationRectangle.Y,
            destinationRectangle.Width, 
            (destinationRectangle.Height * _Reflectivity) / 255);

        // Draw the image on the original graphics
        graphics.DrawImage(reflectedImage, imageRectangle);

        // Finish the reflection using a gradiend brush
        LinearGradientBrush brush = new LinearGradientBrush(imageRectangle,
               Color.FromArgb(255 - _Reflectivity, _BackgroundColor),
                _BackgroundColor, 90, false);
        graphics.FillRectangle(brush, imageRectangle);
    }

    return newImage;
}

Points of interest

The algorithm presented in this article is quite simple. If you're searching for something more advanced (yet less automatic), try this one:

History

  • 28/02/08 – Initial release.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Kel_

Software Developer (Senior)

Belgium Belgium

Member

Follow on Twitter Follow on Twitter
Roman Atachiants (aka Kel) is a software engineer and scientist with extensive experience in different computer science domains, programming languages/principles/patterns & frameworks.
 
Founder and active developer of the Spike-Engine Project: www.spike-engine.com, a real-time networking library with automatic proxy generation.
 
His main expertise consists of C# and .Net platform, Video Gaming technology, Data Bases and Artificial Intelligence. He has an extensive programming knowledge and R&D expertise. He successfully designed various large software systems: from CRMs and ERPs to video games and on-demand movie distribution system.

 


Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralMy vote of 5 Pinmembermanoj kumar choubey3:20 18 Feb '12  
GeneralNice Code PinmemberNNTBIZ23:16 28 Jun '09  
GeneralGreat Article but problem with Transparent Background Pinmemberf r i s c h3:19 21 Mar '09  
GeneralI made a slightly improved version... PinmemberDanBystrom20:57 16 Jan '09  
GeneralRe: I made a slightly improved version... PinmemberBiswas, Sumit19:20 17 Feb '09  
GeneralRe: I made a slightly improved version... PinmemberKel_1:37 18 Feb '09  
GeneralThis is so FAKE, that doen't even look like reflection Pinmemberakirilov2:21 30 May '08  
GeneralRe: This is so FAKE, that doen't even look like reflection PinmemberBiswas, Sumit19:09 17 Feb '09  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web03 | 2.5.120517.1 | Last Updated 28 Feb 2008
Article Copyright 2008 by Kel_
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid