- •Отображение графической информации с использованием HttpHandler
- •Отображение графической информации с использованием дополнительной страницы
- •Возможности преобразований графических файлов при их отображении на сайте
- •Вывод рисунков на Web сайт
- •Возможности преобразования форматов графических файлов с использованием класса Bitmap
- •Возможности сжатия и трансформации графических файлов, преобразованных в формат jpg
- •Сжатие формата jpg
- •Трансформация файла формата jpg
- •Возможности сжатия графических файлов изменением числа бит на пиксель и их трансформации
- •Использование метода DrawImage для работы с графическими файлами
- •Трансформация и прозрачность изображений
- •Имитация прозрачного фона и вывод рисунков с прозрачным фоном
Трансформация файла формата jpg
Код, обеспечивающий вывод трансформированных графических файлов формата jpg на сайт, практически полностью аналогичен приведенному выше и, поэтому, приводится здесь с минимальными комментариями:
string sFileName = string.Empty;
sFileName = Request.QueryString.Get(0);
//Ищем кодек для jpeg
string sMimeType = "image/jpeg";
ImageCodecInfo[] imagecodecinfo = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo jpimagecodecinfo = null;
for (int i = 0; i < imagecodecinfo.Length; i++)
{
if (imagecodecinfo[i].MimeType == sMimeType)
{
jpimagecodecinfo = imagecodecinfo[i];
break;
}
}
if (jpimagecodecinfo == null)
{
Response.End();
return;
}
EncoderParameters encoderparameters = new EncoderParameters(1);
//Здесь задаются параметры трансформации (EncoderValue)
EncoderParameter encoderparameter =
new EncoderParameter(System.Drawing.Imaging.Encoder.Transformation,
(long)EncoderValue.TransformRotate90);
encoderparameters.Param[0] = encoderparameter;
System.Drawing.Image image = System.Drawing.Image.FromFile(sFileName);
MemoryStream memorystream = new MemoryStream();
//Изображение обязательно переводим в jpg
image.Save(memorystream, ImageFormat.Jpeg);
image.Dispose();
//Помещаем в привычный Bitmap
Bitmap bitmap = new Bitmap(memorystream);
memorystream.Flush();
memorystream = new MemoryStream();
//Вносим трансформацию
bitmap.Save(memorystream, jpimagecodecinfo, encoderparameters);
//Выводим на сайт
Response.ContentType = sMimeType;
byte[] b = memorystream.GetBuffer();
Response.BinaryWrite(b);
bitmap.Dispose();
memorystream.Dispose();
Возможности сжатия графических файлов изменением числа бит на пиксель и их трансформации
Как мы отметили выше, методы, применяемые для сжатия bmp файлов, связанные с изменением числа бит на пиксель (оптимизация палитры или "огрубление" цветов), дают эффект и при работе с другими типами файлов (минимальный для jpeg и не дают эффекта для gif, emf, wmf, ico). Для jpg, gif, emf, wmf и ico файлов, при использовании приведенных ниже примеров, можно говорить только о трансформации (поворотах).
string sFileName = Request.QueryString.Get(0);
Bitmap bitmap = new Bitmap(sFileName);
//Поддерживает PixelFormat Format16bppRgb555 Format16bppRgb556
//Format24bppRgb Format32bppRgb
Bitmap bitmap1 = new Bitmap(bitmap.Width, bitmap.Height, PixelFormat.Format16bppRgb565);
Graphics g = Graphics.FromImage(bitmap1);
g.DrawImage(bitmap, 0, 0, bitmap.Width, bitmap.Height);
g.Save();
//Можно перевернуть изображение
bitmap1.RotateFlip(RotateFlipType.Rotate90FlipY);
//Сохраняем в файле для контроля размера
bitmap1.Save(@"Путь\имя_файла.bmp", ImageFormat.Bmp);
//Выводим на сайт в Png
MemoryStream memorystream = new MemoryStream();
bitmap1.Save(memorystream, ImageFormat.Png);
byte[] b = memorystream.GetBuffer();
Response.ContentType = "image/png";
Response.BinaryWrite(b);
Предварительное преобразование к bmp формату так же, как и в предыдущем примере, эффективно для сжатия только bmp, png и tiff файлов.
string sFileName = Request.QueryString.Get(0);
MemoryStream memorystream = new MemoryStream();
System.Drawing.Image image = System.Drawing.Image.FromFile(sFileName);
image.Save(memorystream, ImageFormat.Bmp);
image.Dispose();
//Помещаем в привычный Bitmap
Bitmap bitmap = new Bitmap(memorystream);
memorystream.Flush();
Bitmap bitmap1 = new Bitmap(bitmap.Width, bitmap.Height, PixelFormat.Format24bppRgb);
Graphics g = Graphics.FromImage(bitmap1);
g.DrawImage(bitmap, 0, 0, bitmap.Width, bitmap.Height);
g.Save();
//Можно перевернуть изображение
bitmap1.RotateFlip(RotateFlipType.Rotate90FlipY);
//Сохраняем в файле для контроля размера
bitmap1.Save(@"Папка\Имя_файла.bmp", ImageFormat.Bmp);
//Выводим на сайт в Png
memorystream = new MemoryStream();
bitmap1.Save(memorystream, ImageFormat.Png);
byte[] b = memorystream.GetBuffer();
Response.ContentType = "image/png";
Response.BinaryWrite(b);
Идея уменьшения изображения за счет выбрасывания каждого второго или n-го пикселя используется во многих графических редакторах при сжатии битовых матриц (и не только). В принципе, этот метод почти всегда дает неплохие результаты при малых значениях n и больших размерах картинок, и потеря качества при n=2, например, практически незаметна при размерах изображения 100*100pix. Приведенный ниже код справляется с вращением и масштабированием файлов всех форматов, рассматриваемых нами (единственный недостаток - время вращения больших картинок).
protected void Page_Load(object sender, EventArgs e)
{
try
{
string sFileName = Request.QueryString.Get(0);
MemoryStream memorystream = new MemoryStream();
//Повернуть вокруг вертикальной оси, сжать по осям в 2 раза,
//сделать черно белой
vRotate(sFileName, 2, 2,true,out memorystream);
byte[] b = memorystream.GetBuffer();
Response.BinaryWrite(b);
memorystream.Flush();
memorystream.Dispose();
}
catch (Exception ex)
{
Response.End();
return;
}
}
private void vRotate(string sFileName,
int i, int k, bool gray, out MemoryStream ms)
{
//i=0 - без поворотов
//i=1 - поворот вокруг горизонтальной оси
//i=2 - поворот вокруг вертикальной оси
//i=3 - поворот на 90 градусов вправо
//i=4 - поворот на 180 градусов вправо
//i=5 - поворот на 90 градусов влево
//k - коэффециэнт сжатия по Х и У
//gray = true - сделать черно белой
Bitmap bmp1 = new Bitmap(sFileName);
int X = 0;
int Y = 0;
Bitmap bmp2 = null;
switch (i)
{
case 0:
case 2:
case 4:
bmp2 = new Bitmap(bmp1.Width / k, bmp1.Height / k);
X = bmp1.Width;
Y = bmp1.Height;
break;
case 3:
case 5:
bmp2 = new Bitmap(bmp1.Height / k, bmp1.Width / k);
X = bmp1.Height;
Y = bmp1.Width;
break;
}
Color color;
int r=0;
int g=0;
int b=0;
for (int y = Y - 1; y >= 0; y -= k)
{
for (int x = 0; x < X; x += k)
{
try
{
switch (i)
{
case 0:
r = bmp1.GetPixel(x, y).R;
g = bmp1.GetPixel(x, y).G;
b = bmp1.GetPixel(x, y).B;
break;
case 1:
r = bmp1.GetPixel(bmp1.Width - x - 1, y).R;
g = bmp1.GetPixel(bmp1.Width - x - 1, y).G;
b = bmp1.GetPixel(bmp1.Width - x - 1, y).B;
break;
case 2:
r = bmp1.GetPixel(x, bmp1.Height - y - 1).R;
g = bmp1.GetPixel(x, bmp1.Height - y - 1).G;
b = bmp1.GetPixel(x, bmp1.Height - y - 1).B;
break;
case 3:
r = bmp1.GetPixel(y, bmp1.Height - x - 1).R;
g = bmp1.GetPixel(y, bmp1.Height - x - 1).G;
b = bmp1.GetPixel(y, bmp1.Height - x - 1).B;
break;
case 4:
r = bmp1.GetPixel(bmp1.Width - x - 1, bmp1.Height - y - 1).R;
g = bmp1.GetPixel(bmp1.Width - x - 1, bmp1.Height - y - 1).G;
b = bmp1.GetPixel(bmp1.Width - x - 1, bmp1.Height - y - 1).B;
break;
case 5:
r = bmp1.GetPixel(bmp1.Width - y - 1, x).R;
g = bmp1.GetPixel(bmp1.Width - y - 1, x).G;
b = bmp1.GetPixel(bmp1.Width - y - 1, x).B;
break;
}
if (gray)
{
r = (r + g + b) / 3;
color = Color.FromArgb(r, r, r);
bmp2.SetPixel(x / k, y / k, color);
}
else
{
color = Color.FromArgb(r, g, b);
bmp2.SetPixel(x / k, y / k, color);
}
}catch(Exception)
{
}
}
}
ms = new MemoryStream();
//Для контроля размера файла - можем сохранить в файл
//bmp2.Save(@"C:\Ab\a01.bmp", ImageFormat.Bmp);
bmp2.Save(ms, ImageFormat.Bmp);
ms.Flush();
ms.Dispose();
bmp1.Dispose();
bmp2.Dispose();
}