이미지 품질에 영향을주지 않고 이미지 크기를 조정하려면 어떻게해야합니까?
이미지 품질에 영향을주지 않고 이미지 크기를 조정하려면 어떻게해야합니까?
답변:
으로 RCAR는 말한다, 당신은 어떤 품질을 잃지 않고, 최고의 당신은 C #에서 할 수 없습니다 :
Bitmap newImage = new Bitmap(newWidth, newHeight);
using (Graphics gr = Graphics.FromImage(newImage))
{
gr.SmoothingMode = SmoothingMode.HighQuality;
gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
gr.DrawImage(srcImage, new Rectangle(0, 0, newWidth, newHeight));
}
벡터 그래픽을 사용하지 않는 한 이미지 품질을 잃지 않고 이미지 크기를 조정할 수있는 방법이 없습니다.
private static Image resizeImage(Image imgToResize, Size size)
{
int sourceWidth = imgToResize.Width;
int sourceHeight = imgToResize.Height;
float nPercent = 0;
float nPercentW = 0;
float nPercentH = 0;
nPercentW = ((float)size.Width / (float)sourceWidth);
nPercentH = ((float)size.Height / (float)sourceHeight);
if (nPercentH < nPercentW)
nPercent = nPercentH;
else
nPercent = nPercentW;
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
Bitmap b = new Bitmap(destWidth, destHeight);
Graphics g = Graphics.FromImage((Image)b);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
g.Dispose();
return (Image)b;
}
당신이하려는 것은 당신의 이미지를 "크기 조정 / 리샘플링"하는 것입니다. 다음은 지침을 제공하고 유틸리티 클래스를 제공하는 좋은 사이트입니다.
http://www.codeproject.com/KB/GDI-plus/imgresizoutperfgdiplus.aspx
크기를 조정하지 않으면 래스터 그래픽으로이 작업을 수행 할 수 없습니다.
좋은 필터링과 다듬기로 할 수있는 일은 눈에 띄는 품질 을 잃지 않고 크기를 조정하는 것 입니다.
이미지의 DPI 메타 데이터를 변경할 수도 있습니다 (일부 포함한다고 가정). 정확히 동일한 픽셀 수를 유지하지만 이미지 편집자가 '실제'측정에서 인식하는 방식을 변경할 수 있습니다.
그리고 모든 기반을 다루기 위해 실제 이미지 크기가 아닌 이미지의 파일 크기 만 의미했다면 이미지 데이터의 무손실 인코딩을 살펴볼 것을 제안합니다. 이에 대한 제 제안은 이미지를 .png 파일로 다시 저장하는 것입니다 (그림판을 Windows의 이미지에 대한 무료 트랜스 코더로 사용하는 경향이 있습니다. 그림판에서 이미지로드, 새 형식으로 저장)
픽셀 수를 줄이기 때문에 품질 손실없이 이미지 크기를 조정할 수 없습니다.
브라우저는 이미지 크기를 잘 조정하지 않기 때문에 클라이언트 측 크기를 줄이지 마십시오.
할 수있는 일은 렌더링하기 전에 또는 사용자가 업로드 할 때 프로그래밍 방식으로 크기를 변경하는 것입니다.
다음은 C #에서이 작업을 수행하는 한 가지 방법을 설명하는 문서입니다. http://www.codeproject.com/KB/GDI-plus/imageresize.aspx
이 오픈 소스 ASP.NET 모듈 의 이미지 크기 조정 품질이 마음에 드는지 확인하십시오 . 라이브 데모가 있으므로 직접 조작 할 수 있습니다. Photoshop 출력과 구별하기 어려운 결과를 산출합니다. 또한 비슷한 파일 크기를 가지고 있습니다. MS는 JPEG 인코더에서 좋은 일을했습니다.
거기에는 상황 인식 크기 조정이 있으며 사용할 수 있는지 모르겠지만 살펴볼 가치가 있습니다.
멋진 비디오 데모 (확대가 중간에 나타남) http://www.youtube.com/watch?v=vIFCV2spKtg
여기에 몇 가지 코드가있을 수 있습니다. http://www.semanticmetadata.net/2007/08/30/content-aware-image-resizing-gpl-implementation/
과잉 이었나요? 확대 된 이미지에 적용하여 픽셀을 약간 흐리게하기 위해 적용 할 수있는 쉬운 필터가있을 수 있습니다.
더 크거나 작게 크기를 조정하고 있습니까? 작은 % 또는 2x, 3x와 같은 더 큰 요소로? 애플리케이션의 품질이란 무엇을 의미합니까? 그리고 어떤 유형의 이미지-사진, 딱딱한 선 그리기 또는 무엇입니까? 저수준 픽셀 그라인딩 코드를 작성하거나 기존 라이브러리 (.net 등)로 가능한 한 많이 수행하려고합니까?
이 주제에 대한 많은 지식이 있습니다. 핵심 개념은 보간입니다.
검색 권장 사항 :
* http://www.all-in-one.ee/~dersch/interpolator/interpolator.html
* http://www.cambridgeincolour.com/tutorials/image-interpolation.htm
* C #의 경우 : https : //secure.codeproject.com/KB/GDI-plus/imageprocessing4.aspx?display=PrintAll&fid=3657&df=90&mpp=25&noise=3&sort=Position&view=Quick&fr=26&select=629945
* 이것은 자바에 한정되지만 교육적 일 수 있습니다 -http : //today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html
여기에서이 클래스에 워터 마크 코드를 추가 할 수도 있습니다.
public class ImageProcessor
{
public Bitmap Resize(Bitmap image, int newWidth, int newHeight, string message)
{
try
{
Bitmap newImage = new Bitmap(newWidth, Calculations(image.Width, image.Height, newWidth));
using (Graphics gr = Graphics.FromImage(newImage))
{
gr.SmoothingMode = SmoothingMode.AntiAlias;
gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
gr.DrawImage(image, new Rectangle(0, 0, newImage.Width, newImage.Height));
var myBrush = new SolidBrush(Color.FromArgb(70, 205, 205, 205));
double diagonal = Math.Sqrt(newImage.Width * newImage.Width + newImage.Height * newImage.Height);
Rectangle containerBox = new Rectangle();
containerBox.X = (int)(diagonal / 10);
float messageLength = (float)(diagonal / message.Length * 1);
containerBox.Y = -(int)(messageLength / 1.6);
Font stringFont = new Font("verdana", messageLength);
StringFormat sf = new StringFormat();
float slope = (float)(Math.Atan2(newImage.Height, newImage.Width) * 180 / Math.PI);
gr.RotateTransform(slope);
gr.DrawString(message, stringFont, myBrush, containerBox, sf);
return newImage;
}
}
catch (Exception exc)
{
throw exc;
}
}
public int Calculations(decimal w1, decimal h1, int newWidth)
{
decimal height = 0;
decimal ratio = 0;
if (newWidth < w1)
{
ratio = w1 / newWidth;
height = h1 / ratio;
return height.To<int>();
}
if (w1 < newWidth)
{
ratio = newWidth / w1;
height = h1 * ratio;
return height.To<int>();
}
return height.To<int>();
}
}