Помогите ресайзить изображение,

Viktor Bartel
Дата: 15.05.2006 11:40:40
Добрый день,

У меня возникла проблема с изменением разрешения изображения, вот в инете нашел следующий код:
  protected Bitmap ResizeBitmap(Bitmap b, int nWidth, int nHeight)
  {
    Bitmap result = new Bitmap(nWidth, nHeight);
    try
    {
      using (Graphics g = Graphics.FromImage((System.Drawing.Image)result))
      {
        g.DrawImage(b, 0, 0, nWidth, nHeight);
        g.Dispose();
      }
    }
    catch (Exception ex)
    {
      throw ex;
    }
    return result;
  }
На первый взгляд вроде работает корректно, но вот присмотревшись заметил что при уменьшении разрешения, размер изображения увеличивается вторе, т.е. 800х600(100кб) --> 800х600(1100кб), или 800х600(100кб) --> 320х200(170кб). Но это полбеды, другая беда в том что обработанное изображение невозможно отабразоть в браузере. Почмему так получается? Не подскажете что можно сделать? Неужели в .NET нет собственной функции для изменения развертки?

Заранее вам благодарен.

--
Cordialement
Victor Bartel
M234
Дата: 15.05.2006 11:46:10
Думаю, что смогу вам помочь если вы по порядку объясните чего вы делаете и чего хотите получить в итоге. А то как-то сумбурно и терминология странная.
Разрешение это нечто что например в DPI измеряется. А вы вроде как размер изображения менять хотите или ? Какой формат на выходе - такой и размер.
Вам чего КОНКРЕТНО надо ? Какая задача ?
M234
Дата: 15.05.2006 11:54:00
Вам пропорции сохранять надо при изменении размеров или точно заданных размеров делать ? Тогда правда картинка может быть растянута/сплющена...
Viktor Bartel
Дата: 15.05.2006 12:04:50
А извините за неясность,

Вобщем в реалии я создаю фото-галерею, одна из функционалных возможностей галереии это: аплоад изображения пользователями. Т.е. господин Н. наделал интерсных фотографий и хочет поместит их на сайте клиента. Представим что все фото которые хочет закачать наш Н. имеют разрешения(resolution) 1280х1024, это представляет проблему т.к. если такое изображение поместить на вебстраницу, то сами понимаете что получится. Так вот, при загрузге пользователем изображений я бы хотел проверять разрешение(resolution) изображения и если оное больше чем 600х400, то уменьшать его разрешение(resize) до предела в 600х400.
--
Cordialement
Victor Bartel
Viktor Bartel
Дата: 15.05.2006 12:05:56
M234
Вам пропорции сохранять надо при изменении размеров или точно заданных размеров делать ? Тогда правда картинка может быть растянута/сплющена...

Да очень желательно сохранять пропорции.
Moristar
Дата: 15.05.2006 12:14:15
Вот я когда-то чей-то пример менял - нужно глянуть, что-то подправить

public Image ScaleByPercent(Image imgPhoto, int Width, int Height/*int Percent*/) {
			//float nPercent = ((float)Percent/100);

			int sourceWidth = imgPhoto.Width;
			int sourceHeight = imgPhoto.Height;
			int sourceX = 0;
			int sourceY = 0;

			int destX = 0;
			int destY = 0; 
			int destWidth  = Width;//(int)(sourceWidth * nPercent);
			int destHeight = Convert.ToInt32((sourceHeight*Width)/sourceWidth);//(int)(sourceHeight * nPercent);
			if(destHeight > Height) destHeight = Height;

			Bitmap bmPhoto = new Bitmap(destWidth, destHeight, 
				System.Drawing.Imaging.PixelFormat.Format24bppRgb);
			bmPhoto.SetResolution(imgPhoto.HorizontalResolution, 
				imgPhoto.VerticalResolution);

			Graphics grPhoto = Graphics.FromImage(bmPhoto);
			grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

			grPhoto.DrawImage(imgPhoto, 
				new Rectangle(destX,destY,destWidth,destHeight),
				new Rectangle(sourceX,sourceY,sourceWidth,sourceHeight),
				GraphicsUnit.Pixel);

			grPhoto.Dispose();
			return bmPhoto;
		}
M234
Дата: 15.05.2006 12:28:45
Аааа, теперь более-менее понятно.
Несколько замечаний, если позволите:

1) Я бы закачивал (сохранял на сервере) всё-таки оригиналы фоток, что бы их потом в оригинале и скачаивать/просматривать при надобности. А вот на сайте конечно показывал бы миниатюры удобного размера.

2) Размер 600х400 имеет отношение сторон 3и к 2ум. Это не очень удобно, т.к. большинство цифровых ФА такого формата вообще не имеют (Sony и Kodak имеют 3:2) а в основном 4:3. При несовпадении форматов у вас будут балки на миниатюре, либо сверху/снизу либо справа/слева.

3)Если речь идёт о фотках, то это на 90 % JPEG-файлы, сохранять миниатюры лучше тоже в JPEG и тут можно поиграться с какчеством JPEG, для изменения рзмера файла.

Код:

Функция вписывает картинку в "рамку" заданных размеров:

private Bitmap FixedSize(Bitmap imgPhoto, int Width, int Height)
		{
			int sourceWidth = imgPhoto.Width;
			int sourceHeight = imgPhoto.Height;
			int sourceX = 0;
			int sourceY = 0;
			int destX = 0;
			int destY = 0; 

			float nPercent = 0;
			float nPercentW = 0;
			float nPercentH = 0;

			nPercentW = ((float)Width/(float)sourceWidth);
			nPercentH = ((float)Height/(float)sourceHeight);
			if(nPercentH < nPercentW)
			{
				nPercent = nPercentH;
				destX = System.Convert.ToInt16((Width - 
					(sourceWidth * nPercent))/2);
			}
			else
			{
				nPercent = nPercentW;
				destY = System.Convert.ToInt16((Height - 
					(sourceHeight * nPercent))/2);
			}

			int destWidth  = (int)(sourceWidth * nPercent);
			int destHeight = (int)(sourceHeight * nPercent);

			Bitmap bmPhoto = new Bitmap(Width, Height, 
				imgPhoto.PixelFormat);
			bmPhoto.SetResolution(imgPhoto.HorizontalResolution, 
				imgPhoto.VerticalResolution);

			Graphics grPhoto = Graphics.FromImage(bmPhoto);
			grPhoto.Clear(Color.Black); // Цвет балок.
			grPhoto.InterpolationMode =	InterpolationMode.Bilinear;// Интерполяция

			grPhoto.DrawImage(imgPhoto, 
				new Rectangle(destX,destY,destWidth,destHeight),
				new Rectangle(sourceX,sourceY,sourceWidth,sourceHeight),
				GraphicsUnit.Pixel);

			grPhoto.Dispose();
			return bmPhoto;
		}


Функция изменяет размер в зависимости от заданного процента от оригинала:

static Bitmap ScaleByPercent(Bitmap imgPhoto, float nPercent, InterpolationMode iMode)
		{
			//float nPercent = ((float)Percent/100);
		
			int sourceWidth = imgPhoto.Width;
			int sourceHeight = imgPhoto.Height;
			int sourceX = 0;
			int sourceY = 0;

			int destX = 0;
			int destY = 0; 
			int destWidth  = (int)(sourceWidth * nPercent);
			int destHeight = (int)(sourceHeight * nPercent);

			
			Bitmap bmPhoto = new Bitmap(destWidth, destHeight, 
				imgPhoto.PixelFormat);
			bmPhoto.SetResolution(imgPhoto.HorizontalResolution, 
				imgPhoto.VerticalResolution);

			Graphics grPhoto = Graphics.FromImage(bmPhoto);
			grPhoto.InterpolationMode = iMode;
			grPhoto.DrawImage(imgPhoto, 
				new Rectangle(destX,destY,destWidth,destHeight),
				new Rectangle(sourceX,sourceY,sourceWidth,sourceHeight),
				GraphicsUnit.Pixel);
			
			grPhoto.Dispose();
			grPhoto = null;
			return bmPhoto;
						
		}

Не забудте, на входе ф-ий битмап.

А так будет JPEG в нужном какчестве:
Bitmap b = Bitmap.FromFile("a.jpg");
EncoderParameters ep = new EncoderParameters(1);
ImageCodecInfo icJPG = getCodecInfo("image/jpeg");
// jpeg quality
ep.Param[0] = new EncoderParameter(Encoder.Quality, (long) 80);
b.Save("b.jpg", icJPG, ep);
Viktor Bartel
Дата: 15.05.2006 12:29:43
Спасибо я посмотрю. A в этом примере пропорции учитиваются?
--
Cordialement
Victor Bartel
M234
Дата: 15.05.2006 12:30:35
M234

Не забудте, на входе ф-ий битмап.



...и на выходе.
M234
Дата: 15.05.2006 12:32:36
Viktor Bartel
Спасибо я посмотрю. A в этом примере пропорции учитиваются?
--
Cordialement
Victor Bartel


Да, я же сказал: ВПИСЫВАЕТ в рамку. Пропорции сохраняются.