Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛАБ4 ЛабграфWEB_.doc
Скачиваний:
7
Добавлен:
14.05.2015
Размер:
415.23 Кб
Скачать

Трансформация файла формата 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();

}