Hi,
Dave Harvey wrote:
I have developed a standard .NET control which displays medical images and
works fine in applications, but increasingly, my customers are wishing to use
it in an ASP.NET environment, so I am looking to make a WebControl based
equivalent. [If I'm missing something important, and there is a way to use
my "normal" control, then please stop me at this point and tell me how!]
There is a way to add winforms controls into web pages, but it works
only in very specific conditions (IE on Windows, and IIRC the framework
must be installed on the client) and I recommend against it.
So, assuming that I need to render using HTML - how can I pass "bitmap" data
into such a control for it to be displayed. I'm open to all possible routes,
but I've not yet found one which works. Ideas I have considered include:
1) Putting the data into an <Object- base 64 encoded, and referencing from
a standard <IMGtag. I'm told that this works in other browsers, but it not
supported by IE, which most of my customers use.
2) making a huge "table" to specify the image as one pixel = one cell.
Obviously it would work, but would be huge!
3) Using a standard IMG tag, and somehow referencing the control through a
special URL which would cause the control to return the required bitmap as
JPG, BMP etc. This should be the best (I guess) but I have no idea how to
wire the IMG and the supporting service, especially in a way which will be
transparent to my users!
I would use something like that:
<img src="somepage.aspx?image=hello.bmp" />
This is only an example. There are other ways to do that (for example
using HttpModules) and avoiding to have a page. However, for a starter,
this way is easier.
On the server, create a Page named somepage.aspx. Then, when a request
arrives, you can use the Request.QueryString collection to read the
parameter named "image" (in this case it's called hello.bmp). Of course,
you can have other values for example the whole path of the image to
render, if it exists on the server), or any parameter allowing your
server-side code to render the image dynamically.
Once you know how the image looks like, you can write an image to the
Response.
The example hereunder reads an image existing on the server, and creates
a thumbnail (a smaller view) of the image dynamically. I think that you
can use that as an example. In your case, instead of creating the
thumbnail, you can
IS there are way to do this, or is it a glaing hole in the whole
"CodeBehind" scheme?
The only limit to CodeBehind is imagination ;-)
Example of thumbnail:
// In OnInit, check if the page must render itself,
// or only the thumbnail
if ( Request.QueryString != null
&& Request.QueryString[ ID_QUERY_THUMBNAIL ] != null )
{
m_eAction = EAction.eRenderThubnail;
// thumbnails is of type CThumbnailMaker, responsible to produce
// thumbnails.
thumbnails.RenderThumbnail( this,
Request.QueryString[ ID_QUERY_THUMBNAIL ] );
return;
}
// Note: If m_eAction is set to EAction.eRenderThumbnail,
// the page must not be rendered. --In Render:
protected override void Render( HtmlTextWriter writer )
{
if ( m_eAction != EAction.eRenderThubnail )
{
// Render the page normally
base.Render( writer );
}
}
In the thumbnails class, render the thumbnail:
public void RenderThumbnail( Page oPage,
string strUrlFileName )
{
oPage.Response.ContentType = "image/jpeg";
try
{
RenderThumbnail( oPage.Response.OutputStream,
strUrlFileName );
oPage.Response.StatusCode = 200;
}
catch ( Exception )
{
// Return a file not found code
oPage.Response.StatusCode = 404;
}
}
with:
// I separate these two methods because the last one is
// generic, rendering to any outputstream, not just
// to a System.Web.UI Page class.
private void RenderThumbnail( Stream streamOutput,
string strUrlFileName )
{
string strPath = Context.Request.MapPath( strUrlFileName );
if ( !File.Exists( strPath ) )
{
throw new FileNotFoundException( "Picture not found: " + strPath );
}
Bitmap bmpOriginal = new Bitmap( strPath );
// Calculate the thumbnail's new size. The property m_iMaxSize
// determine the maximum width, resp. height, for example 120 pixels.
int iNewHeight = m_iMaxSize;
float fRate = (float) iNewHeight / (float) bmpOriginal.Height;
int iNewWidth = (int) Math.Round( (float) bmpOriginal.Width * fRate );
if ( iNewWidth m_iMaxSize )
{
iNewWidth = m_iMaxSize;
fRate = (float) iNewWidth / (float) bmpOriginal.Width;
iNewHeight = (int) Math.Round( (float) bmpOriginal.Height * fRate );
}
Bitmap bmpNew = new Bitmap( bmpOriginal, iNewWidth, iNewHeight );
bmpNew.Save( streamOutput, bmpOriginal.RawFormat );
bmpOriginal.Dispose();
bmpOriginal = null;
}
Don't forget to Dispose() the bitmap, or else the file will be blocked
by the process.
To use this, I have one page thumbnails.aspx, which displays all
pictures in a folder thumbnailed in a table. The thumbnails don't exist
on the server, they're created dynamically. See it work here:
About this page, two things: The rendering takes more time than with a
standard call to an image existing on the server, because all thumbnails
calls go through one single class, and because they're rendered
dynamically instead of just "read". Also, the thumbnails quality is less
good than when I use a dedicated program to create "static" thumbnails.
HTH,
Laurent
--
Laurent Bugnion, GalaSoft
Software engineering:
http://www.galasoft-LB.ch
PhotoAlbum:
http://www.galasoft-LB.ch/pictures
Support children in Calcutta:
http://www.calcutta-espoir.ch