2010-02-23 46 views
33

Tôi đang phát triển một ứng dụng web ASP.NET 3.5, trong đó tôi cho phép người dùng tải lên hình ảnh jpeg, gif, bmp hoặc png. Nếu kích thước hình ảnh được tải lên lớn hơn 103 x 32, tôi muốn thay đổi kích thước hình ảnh đã tải lên thành 103 x 32. Tôi đã đọc một số bài đăng trên blog và bài viết và cũng đã thử một số mẫu mã nhưng dường như không có tác dụng nào. Có ai thành công trong việc này không?Thay đổi kích thước hình ảnh trong asp.net mà không làm mất chất lượng hình ảnh

+1

bài mã bạn đang sử dụng mà không làm việc, và giải thích theo cách nào đó không hoạt động. – RedFilter

+1

Bạn muốn bắt buộc 103x32? Hay phù hợp nhất? – citronas

+0

'ImageBuilder.Current.Build (tệp HttpPostedFile, đường dẫn chuỗi, ResizeSettings mới (" width = 103 & height = 32 "));' // Sử dụng [Thư viện Resizer Image] (http://imageresizing.net) –

Trả lời

30

tôi đã cùng một vấn đề một khi trở lại và xử lý nó theo cách này:

private Image RezizeImage(Image img, int maxWidth, int maxHeight) 
{ 
    if(img.Height < maxHeight && img.Width < maxWidth) return img; 
    using (img) 
    { 
     Double xRatio = (double)img.Width/maxWidth; 
     Double yRatio = (double)img.Height/maxHeight; 
     Double ratio = Math.Max(xRatio, yRatio); 
     int nnx = (int)Math.Floor(img.Width/ratio); 
     int nny = (int)Math.Floor(img.Height/ratio); 
     Bitmap cpy = new Bitmap(nnx, nny, PixelFormat.Format32bppArgb); 
     using (Graphics gr = Graphics.FromImage(cpy)) 
     { 
      gr.Clear(Color.Transparent); 

      // This is said to give best quality when resizing images 
      gr.InterpolationMode = InterpolationMode.HighQualityBicubic; 

      gr.DrawImage(img, 
       new Rectangle(0, 0, nnx, nny), 
       new Rectangle(0, 0, img.Width, img.Height), 
       GraphicsUnit.Pixel); 
     } 
     return cpy; 
    } 

} 

private MemoryStream BytearrayToStream(byte[] arr) 
{ 
    return new MemoryStream(arr, 0, arr.Length); 
} 

private void HandleImageUpload(byte[] binaryImage) 
{ 
    Image img = RezizeImage(Image.FromStream(BytearrayToStream(binaryImage)), 103, 32); 
    img.Save("IMAGELOCATION.png", System.Drawing.Imaging.ImageFormat.Gif); 
} 

Tôi chỉ đọc rằng đây là cách để có được chất lượng cao nhất.

+0

+1 Đẹp : "Tỷ lệ gấp đôi = Math.Max ​​(xRatio, yRatio);" – Joop

+0

Trong một phiên bản mới, tôi cũng đưa vào tài khoản rằng tôi sẽ không strech hình ảnh, nhưng đó là khá dễ dàng để làm việc ra :-P (gợi ý: 'ration = Math.Min (khẩu phần, 1.0);') – Alxandr

+0

Vâng , có [một vài cài đặt khác sẽ trợ giúp] (http://nathanaeljones.com/163/20-image-resizing-pitfalls/), chẳng hạn như bù đắp pixel. –

0

Tôi đã thực hiện thành công việc này bằng cách tạo bitmap của hình ảnh và sau đó thay đổi kích thước bitmap ... Tôi không chắc đây có phải là cách tốt nhất hay hiệu quả nhất để thực hiện việc này hay không.

Trong trường hợp của tôi, tôi cần phải cắt giảm chiều cao và chiều rộng của hình ảnh xuống một nửa.

Đây là những gì tôi đã làm.

private Image getImageFromBytes(byte[] myByteArray) 
    {       
     System.IO.MemoryStream newImageStream = new System.IO.MemoryStream(myByteArray, 0, myByteArray.Length); 
     Image image = Image.FromStream(newImageStream, true); 
     Bitmap resized = new Bitmap(image, image.Width/2, image.Height/2); 
     image.Dispose(); 
     newImageStream.Dispose(); 
     return resized; 
    } 
41

Đây là mã tôi sử dụng. Nó hỗ trợ xoay, và cũng thiết lập độ phân giải hình ảnh cho các tiêu chuẩn JPEG của 72dpi @ 24-bit màu (theo mặc định GDI + lưu hình ảnh ở 96dpi @ 32-bit màu). Nó cũng khắc phục sự cố biên giới đen/xám mà một số người gặp phải khi thay đổi kích thước hình ảnh.

/// <summary> 
/// Resizes and rotates an image, keeping the original aspect ratio. Does not dispose the original 
/// Image instance. 
/// </summary> 
/// <param name="image">Image instance</param> 
/// <param name="width">desired width</param> 
/// <param name="height">desired height</param> 
/// <param name="rotateFlipType">desired RotateFlipType</param> 
/// <returns>new resized/rotated Image instance</returns> 
public static Image Resize(Image image, int width, int height, RotateFlipType rotateFlipType) 
{ 
    // clone the Image instance, since we don't want to resize the original Image instance 
    var rotatedImage = image.Clone() as Image; 
    rotatedImage.RotateFlip(rotateFlipType); 
    var newSize = CalculateResizedDimensions(rotatedImage, width, height); 

    var resizedImage = new Bitmap(newSize.Width, newSize.Height, PixelFormat.Format32bppArgb); 
    resizedImage.SetResolution(72, 72); 

    using (var graphics = Graphics.FromImage(resizedImage)) 
    { 
     // set parameters to create a high-quality thumbnail 
     graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; 
     graphics.SmoothingMode = SmoothingMode.AntiAlias; 
     graphics.CompositingQuality = CompositingQuality.HighQuality; 
     graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; 

     // use an image attribute in order to remove the black/gray border around image after resize 
     // (most obvious on white images), see this post for more information: 
     // http://www.codeproject.com/KB/GDI-plus/imgresizoutperfgdiplus.aspx 
     using (var attribute = new ImageAttributes()) 
     { 
      attribute.SetWrapMode(WrapMode.TileFlipXY); 

      // draws the resized image to the bitmap 
      graphics.DrawImage(rotatedImage, new Rectangle(new Point(0, 0), newSize), 0, 0, rotatedImage.Width, rotatedImage.Height, GraphicsUnit.Pixel, attribute); 
     } 
    } 

    return resizedImage; 
} 

/// <summary> 
/// Calculates resized dimensions for an image, preserving the aspect ratio. 
/// </summary> 
/// <param name="image">Image instance</param> 
/// <param name="desiredWidth">desired width</param> 
/// <param name="desiredHeight">desired height</param> 
/// <returns>Size instance with the resized dimensions</returns> 
private static Size CalculateResizedDimensions(Image image, int desiredWidth, int desiredHeight) 
{ 
    var widthScale = (double)desiredWidth/image.Width; 
    var heightScale = (double)desiredHeight/image.Height; 

    // scale to whichever ratio is smaller, this works for both scaling up and scaling down 
    var scale = widthScale < heightScale ? widthScale : heightScale; 

    return new Size 
        { 
         Width = (int) (scale * image.Width), 
         Height = (int) (scale * image.Height) 
        }; 
} 
+3

Cảm ơn bạn đã chỉ đến giải pháp cho vấn đề về đường viền màu xám. –

+0

Như trên, cảm ơn khắc phục sự cố biên giới. –

+0

Giải pháp này thay đổi kích thước mà không thay đổi màu sắc hình ảnh gốc! Lam tôt lăm! – danyolgiax

2

Mã được liên kết với việc thay đổi kích thước thực tế của bitmap như sau.

public static Bitmap ResizeBitmap(Bitmap originalBitmap, int requiredHeight, int requiredWidth) 
{ 
    int[] heightWidthRequiredDimensions; 

    // Pass dimensions to worker method depending on image type required 
    heightWidthRequiredDimensions = WorkDimensions(originalBitmap.Height, originalBitmap.Width, requiredHeight, requiredWidth); 


    Bitmap resizedBitmap = new Bitmap(heightWidthRequiredDimensions[1], 
             heightWidthRequiredDimensions[0]); 

    const float resolution = 72; 

    resizedBitmap.SetResolution(resolution, resolution); 

    Graphics graphic = Graphics.FromImage((Image) resizedBitmap); 

    graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 
    graphic.DrawImage(originalBitmap, 0, 0, resizedBitmap.Width, resizedBitmap.Height); 

    graphic.Dispose(); 
    originalBitmap.Dispose(); 
    //resizedBitmap.Dispose(); // Still in use 


    return resizedBitmap; 
} 


private static int[] WorkDimensions(int originalHeight, int originalWidth, int requiredHeight, int requiredWidth) 
{ 
    int imgHeight = 0; 
    int imgWidth = 0; 

    imgWidth = requiredHeight; 
    imgHeight = requiredWidth; 


    int requiredHeightLocal = originalHeight; 
    int requiredWidthLocal = originalWidth; 

    double ratio = 0; 

    // Check height first 
    // If original height exceeds maximum, get new height and work ratio. 
    if (originalHeight > imgHeight) 
    { 
     ratio = double.Parse(((double) imgHeight/(double) originalHeight).ToString()); 
     requiredHeightLocal = imgHeight; 
     requiredWidthLocal = (int) ((decimal) originalWidth * (decimal) ratio); 
    } 

    // Check width second. It will most likely have been sized down enough 
    // in the previous if statement. If not, change both dimensions here by width. 
    // If new width exceeds maximum, get new width and height ratio. 
    if (requiredWidthLocal >= imgWidth) 
    { 
     ratio = double.Parse(((double) imgWidth/(double) originalWidth).ToString()); 
     requiredWidthLocal = imgWidth; 
     requiredHeightLocal = (int) ((double) originalHeight * (double) ratio); 
    } 

    int[] heightWidthDimensionArr = { requiredHeightLocal, requiredWidthLocal }; 

    return heightWidthDimensionArr; 
} 
} 

bài viết trên blog này chứa mã đầy đủ nguồn cho thay đổi kích thước hình ảnh, và nén (nếu có yêu cầu)

http://blog.bombdefused.com/2010/08/bulk-image-optimizer-in-c-full-source.html

Các vấn đề liên quan