- Table of Contents
- .NET Book Recommendations
- What Is .NET?
- The Microsoft .NET Framework
- The Common Language Runtime (CLR), the Common Type System (CTS), and the Common Language Specification (CLS)
- .NET Framework Class Library
- Visual Studio .NET
- .NET Enterprise Servers and .NET My Services
- .NET Compliant Languages
- C#
- Visual Basic .NET (VB .NET)
- ASP.NET
- XML Web Services
- ADO.NET
- XML.NET
- Windows Forms
- Why .NET?
- Displaying Errors with the Error Provider
- COM Interoperability
- Comparing Java and .NET
- Calling Unmanaged Code
- .NET Application Security
- Code Access Security
- .NET Standards Support
- Numeric Types in the .NET Framework
- Working with Strings
- Formatting Strings
- Trimming Character Strings
- Comparing Strings in .NET 2.0
- Arrays and Collections
- Arrays as Class Members
- Sorting a Multi-Dimensional Array
- Sorting a Multi-Dimensional Array with LINQ
- File I/O (System.IO)
- Working with File Names
- Using the File System
- Working with Files and Directories
- Monitoring the File System
- Working with Streams
- Working with Text Encodings
- Working with Date and Time
- Extending the DateTime Class
- Fun with Dates
- Exceptions
- Delegates
- Events
- Asynchronous Programming
- Asynchronous File I/O
- Timers
- Random Numbers
- Cryptographically Secure Random Numbers
- Serialization
- MultiThreading (System.Threading)
- Multi-Threading Overview
- The Managed Thread Pool
- Managed Threading
- Thread Synchronization
- Synchronizing Data Access
- Trace Debugging
- Tracing in .NET 2.0
- ASP.NET Trace
- Validating User Input in ASP.NET Web Pages
- Event Logging
- Monitoring Application Performance
- Accessing the Registry
- Accessing Environment Information
- Environment Variables in .NET 2.0
- Managing Windows Forms Applications
- Working with Email
- Working with Graphics
- Animating a Background
- Working with Images
- Drawing Cycloid Curves
- Simulating the Spirograph
- Building International Web Applications
- .NET Compact Framework
- Mobile Web Development with ASP.NET
- Speech Technologies
- Microsoft MapPoint Web Service
- Working with Typed DataSets
- Using Relationships in DataSets
- DataColumn Expressions
- Playing Simple Sounds
- Playing Sounds with .NET 2.0
- Returning an Image in a Web Page
- RSS
- Best Practices Project Structure
- Best Practices Application Blocks
- The Data Access Application Block
- The Exception Management Application Block
- Best Practices — Performance
- Best Practices — Performance and Scalability
- Best Practices - Testing
- Reading the Tea Leaves, 2005
- Predictions: A Look Back at 2005, and a Look Ahead to 2006
- .NET Downloads
- Application Deployment Overview
- Application Deployment — Versioning
- Application Deployment — Version Policy
- Application Deployment — Packaging and Distribution
- .NET Remoting Overview
- A Remoting Demonstration
- Remoting Configuration
- Remoting: Lifetimes and Leases
- Remoting: Other Issues
- Attributes
- Writing Custom Attributes
- Accessing Attributes in Code
- Reflection
- Class Design: Inheritance, Interface, or Composition?
- The TriTryst Game
- Console Applications in .NET 2.0
- New File I/O Methods in .NET 2.0
- Building Projects with MSBuild
- Unmanaged Callbacks in .NET 2.0
- Timer Troubles
- Non-Rectangular Windows Forms
- Windows Forms Transparency
- 10 Things I Hate About Visual Basic
- 10 Things I Hate About C#
- Background Processing with Idle Time
- Scaling Windows Forms
- Reading and Writing Binary Data
- New Memory Management Functions in .NET 2.0
- Compatibility Between .NET 1.1 and .NET 2.0
- Managed Debugging Assistants in .NET 2.0
- XDir: A Program for Viewing Directory Sizes
- The Microsoft.VisualBasic Namespace
- Operator Overloading
- Working with GPS Data
- Hidden Visual Studio Tools
- .NET 3.0
- The .NET 2.0 Stopwatch Class
- Nullable Types
- Drawing Rotated Text
- Unsafe Code
- Other .NET Languages
- Compiler Directives
- Safe Handles
- Predictions, 2007 Edition
- New Features in C# 3.0
- Generics
- Network Client Programming
- On the Misuse of Exceptions
- Maximum Object Size in .NET
- More on Maximum Object Sizes
- Keyed Collection Memory Limitations
- Matching String Endings
- Allocating Small Data Structures
- Grumbling About Limitations
- Some Thoughts on the Nature of What We Do
- Working with Predicates in Collections
- Working with DataReaders
- Outputting XML with XmlWriter
- Writing XML Data
- Working with Compression
- Another Look at Compressed Streams
- Compressing a Very Large File
- Canonical URIs
- Constructing URIs
- Using OneWayAttribute for Remote Calls
- Selecting a Garbage Collector
- Linked List
- Linked List Application - The MRU List
- Auto-implemented Properties in C#
- The HashSet Collection
- Looking Ahead: 2018
- An Experiment in Optimization
- A Larger Integer
- Extension Methods
- Language Integrated Query (LINQ)
- Variable Length Parameter Lists
- The ReaderWriterLockSlim Synchronization Primitive
- Sorting a Text File
- Sorting a Large Text File
- Using ListView with Large Data Sets
- LINQ One-Liners
- Regular Expression Optimization
- Random File I/O
- Computing the Size of a Structure
- More on Computing Structure Sizes
- UnmanagedMemoryStream
- Dynamically Loading Code
- Building a String Table
- Delegates Versus Function Pointers
- Visual Studio Editor Features
- A Simple Profile Timer
- New Features in C# 4.0
- IEnumerator or IList?
- New Features in .NET 4.0
- Set Operations with IEnumerable and HashSet
- Using File Locks
- Extending Object Functionality
- Clearing a HashSet
- When Hash Codes Matter
- Parsing Command Line Options
- Creating a Single-Instance Program
- Asynchronous Windows Forms Events
- The BackgroundWorker Component
- Fixing a Dumb Mistake
- Thinking About Multi-Threaded Programs
- JavaScript Object Notation
- Useful .NET-related Sites
- Markov Models
- Building an Order 0 Markov Model
- Higher Order Markov Models
- Webmaster's Guide to robots.txt
- An Overview of the Parallel Extensions to .NET
- Parallel Extensions Synchronization Objects
- Thread Safe Collections
- A Bug and a Conundrum
- Another Bug and an Answer
- Task Parallel Library
- Good and Bad Ideas in C#
- Parallel LINQ
- Copying Large Files
- Replacing File.Copy
- Learning from Our Mistakes
- Symbolic Links
- There Is No Easy Fix
- Tracking Hurricanes
- Examining Hurricane Data
- Searching for Multiple Strings
- Simple JSON Processing
- Aho-Corasick String Searching
- Writing a Web Crawler
- Web Crawler Politeness
- Source Control Management
- Subversion
- Communicating with Datagrams
- Fun with Actions and Funcs New
- The Future of Media
- The Importance of Metadata
- Of Comparison and IComparer
- IComparer, Comparer, IComparable, Oh My!
- Comparing Generic Types New
- A Simple HTTP Server New
- Informit Reference Library
Returning an Image in a Web Page
Last updated Dec 16, 2004.
Some Web sites use scripts to serve up all content, even images and other static data. This allows them to more tightly control their content, and limits the number of URLs that are available on the Web site. For example, a picture that you would normally access by browsing to http://www.companyxyz.com/picture1.jpg, you would access instead by visiting http://www.companyxyz.com/picture.aspx?pic=picture1.
Using this technique for static content is most advantageous for companies that have Web sites with quickly changing content and who are concerned about the security ramifications of giving their content developers access to deploy files onto the server.
The technique is also very useful if you want to return a random picture, or a picture that's generated in response to parameters that the user enters on the query string or in a Web page.
Returning a Static Image
Returning a picture from an .aspx program isn't terribly difficult. All you have to do is load or create the picture in a .NET Image object and then write the contents of the Image to the output stream. For example, if you create an ASP.NET page that contains the Page_Load method shown here, it will select one of two different pictures and return it in the request stream:
[C#]
private void Page_Load(object sender, System.EventArgs e)
{
// Get the current time.
// If an odd second, return picture 1. On even seconds return picture 2.
int ss = DateTime.Now.Second;
// load the image
using (System.Drawing.Image img = LoadImage(ss % 2))
{
// and return it as a JPEG file
Response.ContentType = "image/jpeg";
img.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
private System.Drawing.Image LoadImage(int imgNum)
{
string imgName = Server.MapPath(string.Format("picture{0}.jpg", imgNum));
Bitmap bmp = new Bitmap(imgName);
return bmp;
}
[Visual Basic]
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' Get the current time.
' If an odd second, return picture 1. On even seconds return picture 2.
Dim ss As Integer = DateTime.Now.Second
' load the image
Dim img As System.Drawing.Image = LoadImage(ss Mod 2)
Try
Response.ContentType = "image/jpeg"
img.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg)
Finally
img.Dispose()
End Try
End Sub
Function LoadImage(ByVal imgNum As Integer) As System.Drawing.Image
Dim imgName As String = Server.MapPath(String.Format("picture{0}.jpg", imgNum))
Dim bmp As New Bitmap(imgName)
Return bmp
End Function
This code assumes that the pictures are stored in the application's default directory, so I used Server.MapPath to locate them. In a real application, you'd probably have the images stored in a directory that's not accessible from the outside, or in a database as I mentioned earlier. If you want to run this program, you'll have to place two images named picture0.jpg and picture1.jpg in the Web application's directory.
Note that I set the content type to "image/jpeg" before returning the picture. Although this isn't absolutely required, it's a good thing to identify the content type that you're returning.
Generating an Image Dynamically
Returning a dynamically generated image isn't any more difficult than returning an image that you loaded from the disk. Well, except for actually creating the image. You have to create a Bitmap object of the size that you want, draw on it, and then return the resulting image.
Here's a LoadImage method that shows how to do that. It will create a circle on even seconds (imgNum = 0), and a square on odd seconds (imgNum = 1).
[C#]
private System.Drawing.Image LoadImage(int imgNum)
{
Bitmap bmp = new Bitmap(100, 100);
using (Graphics g = Graphics.FromImage(bmp))
{
g.Clear(Color.White);
if (imgNum == 0)
{
g.FillEllipse(Brushes.Blue, 0, 0, 100, 100);
}
else
{
g.FillRectangle(Brushes.Cyan, 0, 0, 100, 100);
}
}
return bmp;
}
[Visual Basic]
Function LoadImage(ByVal imgNum As Integer) As System.Drawing.Image
Dim bmp As New Bitmap(100, 100)
Dim g As Graphics = Graphics.FromImage(bmp)
Try
g.Clear(Color.White)
If imgNum = 0 Then
g.FillEllipse(Brushes.Blue, 0, 0, 100, 100)
Else
g.FillRectangle(Brushes.Cyan, 0, 0, 100, 100)
End If
Finally
g.Dispose()
End Try
Return bmp
End Function
You can replace the LoadImage method from the previous example with this code.
Of course, you can create any size image you like using this technique, and draw whatever you want in it. Once you've created the Bitmap object and created the Graphics object, you have access to all of the GDI+ drawing commands.



Account Sign In
View your cart