Home Download and Buy What's New Live Demos Contact Us
 
8.Miscellaneous

Search this site
 

 

User Manual
Chapter 9: GIF Output Chapter 7: Metadata Extraction Chapter 8: Miscellaneous Features

8.1 CMYK-to-RGB Conversion
8.2 Image Resolution
8.3 Access to Individual Pixels
8.4 Progressive JPEGs
8.5 Brightness, Contrast and Saturation
8.6 Filters
8.7 Chroma Key

8.1 CMYK-to-RGB Conversion

Most digital images we deal with are RGB. That is, the color of each pixel in those images is represented by three components -- red, green and blue (RGB), which correspond to the three cathode emitters in the monitor. In images intended for print, on the other hand, the pixels are represented by four colorants -- cyan, magenta, yellow and black (CMYK), which correspond to the four primary ink colors used in printers.

JPEG and TIFF images created in the CMYK color space cannot always be viewed over the Web, some browsers show them as a "red X" icon. To enable CMYK image viewing, AspJpeg.NET offers the JpegImage.ToRGB method, which converts CMYK images to the RGB color space.

Converting CMYK to RGB is not a trivial task and there is no single "correct" way to do it. To achieve reasonably good color reproduction, the ToRGB method performs a series of complex non-linear color transformations based on profiles, the standard color space definitions established by the International Color Consortium (ICC). For more information on ICC profiles, visit www.color.org.

CMYK-to-RGB conversion is a very CPU-intensive procedure. It is therefore important to call the ToRGB method after the image size has been reduced:

// Fast
objImage.Width = objImage.OriginalWidth / 2;
objImage.Height = objImage.OriginalHeight / 2;
objImage.ToRGB();

// Slow
objImage.ToRGB();
objImage.Width = objImage.OriginalWidth / 2;
objImage.Height = objImage.OriginalHeight / 2;

Jpeg.ToRGB only has effect if the current image is in CMYK or grayscale color spaces. If the image is already an RGB one, the method does nothing.

To see the CMYK-to-RGB functionality in action, run Live Demo #3.

8.2 Image Resolution

Image resolution is information embedded in the image specifying the print quality of this image should it be printed. Resolution is usually expressed in dots-per-inch (DPI). 72 DPI or 96 DPI images are known as low-resolution and 300 DPI and above as high-resolution.

Most image viewers, such as your Web browser, ignore the resolution information and simply use the pixel size of the image for screen rendering. Advanced image management and print systems such as Photoshop do use image resolution to compute the correct size of the image on paper when printed. Note that resolution information is not always embedded in an image. If that is the case, it should be assumed to be 72 DPI.

AspJpeg.NET enables you to retrieve the resolution information from images, and also set new resolution. The properties OriginalResolutionX and OriginalResolutionY return the current DPI resolution along the horizontal and vertical coordinates, respectively. These values are retrieved from the header of the image. Quite often, resolution information is also stored in the form of EXIF fields XResolution and YResolution, and it is not uncommon for the EXIF values to be different from the header values. If that is the case, the EXIF numbers should be considered the "correct" values.

The following code snippet attempts to retrieve the X and Y resolutions from an arbitrary image. It queries the EXIF fields first, and in absence of those, uses the header values.

C#
JpegManager objJpeg = new JpegManager();
string strPath = @"c:\path\image.jpg";
JpegInfo objInfo = objJpeg.OpenInfo(strPath);
float fXRes, fYRes;
if (objInfo["XResolution"] != null && objInfo["YResolution"] != null)
{
    fXRes = (float)objInfo["XResolution"].Value;
    fYRes = (float)objInfo["YResolution"].Value;
}
else
{
    JpegImage objImage = objJpeg.OpenImage(strPath);
    fXRes = objImage.OriginalResolutionX;
    fYRes = objImage.OriginalResolutionY;
}
VB.NET
Sub Page_Load(Source As Object, E As EventArgs)
' Create instance of JpegManager
Dim objJpeg As JpegManager = New JpegManager()

Dim strPath As String = "c:\path\image.jpg"

    Dim objInfo As JpegInfo = objJpeg.OpenInfo(strPath)
    Dim fXRes As Single, fYRes As Single
    If objInfo("XResolution") IsNot Nothing and 
			objInfo("YResolution") IsNot Nothing Then 
        fXRes = CType(objInfo("XResolution").Value, Single)
        fYRes = CType(objInfo("YResolution").Value, Single)
    Else
        Dim objImage As JpegImage = objJpeg.OpenImage(strPath)
        fXRes = objImage.OriginalResolutionX
        fYRes = objImage.OriginalResolutionY
    End If

End Sub

To set new resolution in the image header, use the properties ResolutionX and ResolutionY, as follows:

...
objImage.ResolutionX = 72;
objImage.ResolutionY = 72;
...
objImage.Save( path );

Changing EXIF values is covered in Section 7.8 of the previous chapter.

8.3 Access to Individual Pixels

AspJpeg.NET is capable of setting and retrieving individual pixels of an image via the JpegImage.Pixels property of the type byte []. This parameterized property accepts two arguments [X, Y] which specify the location of the pixel to be set or retrieved. This property is an alias for an indexer with the same arguments. The property returns, or is assigned, a byte array of color components for this pixel. In case of an RGB image, the array must contain exactly three elements. The number of color components in an image can be retrieved via the property JpegImage.OriginalComponents.

C#
// Set pixel (20, 50) to green
objImage.Pixels[20, 50] = new byte [] { 0, 255, 0 };

// Or simply
objImage[20, 50] = new byte [] { 0, 255, 0 };

// Retrieve pixel (15, 20)
byte [] pixel = objImage.Pixels[15, 20];

// Or simply
byte [] pixel = objImage[15, 20];
VB.NET
' Set pixel (20, 50) to green
objImage.Pixels(20, 50) = New Byte(2) { 0, 255, 0 }

' Or simply
objImage(20, 50) = New Byte(2) { 0, 255, 0 }

' Retrieve pixel (15, 20)
Dim pixel As Byte() = objImage.Pixels(15, 20);

' Or simply
Dim pixel As Byte() = objImage(15, 20)

8.4 Progressive JPEGs

A progressive JPEG is the equivalent of an "interlaced" GIF. Such an image can be displayed in full size even if only partially downloaded, although in lower quality. As more and more data arrives, the image progressively becomes sharper and sharper until the entire image has been downloaded. This feature makes progressive images attractive in a slow-connection environment.

With AspJpeg.NET, you can create progressive JPEGs by setting the JpegImage.Progressive property to true:

objImage.Progressive = true;
...
objImage.Save( path );

8.5 Brightness, Contrast and Saturation

AspJpeg.NET is capable of adjusting the brightness, contrast and saturation of an image using the multi-purpose Adjust method. This method expects two parameters: the operation code and the operation-specific value.

To adjust brightness, 1 is passed as the first parameter and a brightness value in the range [-1, 1] is passed as the 2nd parameter. A value greater than 0 increases brightness, a value less than 0 decreases it:

objImage.Adjust( 1, 0.05 );

To adjust contrast, 2 is passed as the first parameter and a contrast value in the range [0.001, 5] is passed as the 2nd parameter. A value greater than 1 increases constrast, a value less than 1 decreases it:

objImage.Adjust( 2, 1.2 );

To adjust saturation, 3 is passed as the first parameter and a saturation value in the range [-1, 1] is passed as the 2nd parameter. A value greater than 0 increases saturation, a value less than 0 decreases it:

objImage.Adjust( 3, -0.2 );

The Adjust method is only applicable to RGB images.

NOTE: Currently, the Adjust method is obsolete. ApplyFilter, a more versatile method described in the following section, should be used instead.

8.6 Filters

AspJpeg.NET offers several common image filters such as brightness, contrast, saturation, blur, sharpness, edge detection and others via a single method, ApplyFilter. This method accepts three arguments: the Filter ID, and two filter-specific parameters. The first parameter is a number, the second is an object value which can be omitted. Some filters require the 1st or 2nd parameter only, others require both, still others none at all.

The following table summarizes all filters currently supported, as applied to the image shown on the right.

NameFilter IDParameter 1Parameter 2Sample Output and Notes
Brightness 1 Brightness amount, a number in the range [-255, 255] Not used

objImage.ApplyFilter(1, 100);

Contrast 2 Contrast amount, a number in the range [-255, 255] Not used

objImage.ApplyFilter( 2, 100 );

Saturation 3 Saturation amount, a number in the range [-100, 100] Not used

objImage.ApplyFilter( 3, -50 );

Gaussian blur 4 Sigma, a positive number Kernel size, an odd number between 3 and 21 (7 by default)

objImage.ApplyFilter( 4, 3, 5 );

Sharpen 5 0 for less sharpening, 1 for more sharpening Not used

objImage.ApplyFilter( 5, 0 );

Generic Convolution 6 Not used Kernel matrix, an array of numbers specifying the relative weights of neighboring pixels to be applied to each pixel of the image. The array's length must be a square number from the set [9, 25, 49, ..., 441]

objImage.ApplyFilter( 6, 0, new int[] {-2, -1, 0, -1, 1, 1, 0, 1, 2} );

Sharpen, blur, emboss and many other filters are based on a generic convolution transformation. The kernel in this example implements an emboss filter.

Threshold 7 Threshold value in the range [0, 255] Not used

objImage.ApplyFilter( 7, 150 );

Converts the image to monochrome (strictly black and white.)

Edge Detection 8 Not used Not used

objImage.ApplyFilter( 8, 0 );

Implements Sobel edge detection algorithm. Converts the image to grayscale.

Note: the ApplyFilter method cannot be used with CMYK images.

8.7 Chroma Key
Chroma Key refers to a visual effect where two images are combined into one in such a way that the monochromatic (usually green or blue) background of the first image is replaced with the second image, while its foreground subject remains intact. It is commonly used for weather forecast broadcasts, among other areas.

AspJpeg.NET implements the chroma key effect via the method DrawImageChromaKey of its JpegCanvas object. This method is similar to the DrawImage method in that it draws one image on top of another, but it does so while removing the monochromatic background of the image being drawn.

The DrawImageChromaKey method expects 8 arguments. The first three are the same as in DrawImage: the X and Y coordinates and an instance of the JpegImage object representing the image to be drawn on the current image. The other 5 arguments control the handling of the monochromatic background of the image being drawn: the RGB values of the key color (the predominant color of the background), and two color distances Dist1 and Dist2. All pixels with the colors closer to the key color than Dist1 are made fully transparent. All pixels with the colors farther from the key color than Dist2 are made fully opaque. All pixels in between are made semi-transparent for better blending. All these arguments are to be chosen by trial and error for each background.

The image above was created using the following code sample:

C#
<%@ Page Language="C#" debug="true" %>

<%@ Import Namespace="Persits.Jpeg"%>

<html>
<head>
    <title>AspJpeg.NET User Manual Chapter 8 - Chroma Key</title>
<script runat="server" languge="C#">

void Page_Load( Object Source, EventArgs E)
{
    // Create instance of JpegManager
    JpegManager objJpeg = new JpegManager();

    string strBkPath = Server.MapPath("../images/gym.jpg");
    string strPath = Server.MapPath("../images/greenscreen.jpg");

    // Open both images
    JpegImage objBackground = objJpeg.OpenImage( strBkPath );
    JpegImage objImage = objJpeg.OpenImage( strPath );

    // Draw image on background, remove green background
    objBackground.Canvas.DrawImageChromaKey( 0, 0, objImage, 
		60, 205, 72, 20, 80 );
    string strFilename = 
		objBackground.SaveUnique(Server.MapPath("chroma.jpg"));

    OutputImage.ImageUrl = strFilename;
}
</script>
</head>

<form runat="server">
    <asp:image runat="server" id="OutputImage"/>
</form>
</html>
VB.NET
<%@ Page Language="vb" debug="true" %>

<%@ Import Namespace="Persits.Jpeg"%>

<html>
<head>
    <title>AspJpeg.NET User Manual Chapter 8 -- Chroma Key</title>
<script runat="server" languge="vb">
Sub Page_Load(Source As Object, E As EventArgs)
    ' Create instance of JpegManager
    Dim objJpeg As JpegManager = New JpegManager()

    Dim strBkPath As String = Server.MapPath("../images/gym.jpg")
    Dim strPath As String = Server.MapPath("../images/greenscreen.jpg")

    ' Open both images
    Dim objBackground As JpegImage = objJpeg.OpenImage(strBkPath)
    Dim objImage As JpegImage = objJpeg.OpenImage(strPath)

    ' Draw image on background, remove green background
    objBackground.Canvas.DrawImageChromaKey(0, 0, 
        objImage, 60, 205, 72, 20, 80)

    Dim strFilename As String =
        objBackground.SaveUnique(Server.MapPath("perspective.jpg"))

    OutputImage.ImageUrl = strFilename
End Sub
</script>
</head>

<form id="Form1" runat="server">
    <asp:image runat="server" id="OutputImage"/>
</form>
</html>

Click the links below to run this code sample:

http://localhost/aspjpeg.net/manual_08/08_chroma.cs.aspx
http://localhost/aspjpeg.net/manual_08/08_chroma.vb.aspx  Make sure AspJpeg.NET is installed on your local machine and IIS is running for these links to work.

Chapter 9: GIF Output Chapter 7: Metadata Extraction 


Advanced Image Management Advanced
Image Management
Component for .NET