使用c#为asp.net Web应用程序将任何图像大小的图像调整为400Wx264H

时间:2012-04-25 13:30:42

标签: c# asp.net jcrop resize-image

我正在设计一个网站,需要将大图像重新调整为400Wx264H的尺寸而不会丢失宽高比。

我已经处理过不同版本的代码,但所有代码都回来了。

现在我正在调整400W的大图像,同时保持纵横比,然后我允许用户使用jCrop选择部分图像,可选区域是350Wx230H。

如果图像的尺寸高度或宽度小于400W或264H像素,则有时它会在图像中添加黑色部分。

如果有人能指出我必须做的类似事情,我将不胜感激。

代码上传和重新调整图像大小如下

public void ResizeImageFreeSize(string OriginalFile, string NewFile, int NewWidth, int MaxHeight, bool OnlyResizeIfWider, string fileExtension)
    {
        System.Drawing.Image FullsizeImage = System.Drawing.Image.FromFile(OriginalFile);
        // Prevent using images internal thumbnail
        //FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);
        //FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);
        //if (OnlyResizeIfWider)
        //{
        //    if (FullsizeImage.Width <= NewWidth)
        //    {
        //        NewWidth = FullsizeImage.Width;
        //    }
        //}
        //int NewHeight = FullsizeImage.Height * NewWidth / FullsizeImage.Width;
        //if (NewHeight > MaxHeight)
        //{
        //    // Resize with height instead
        //    NewWidth = FullsizeImage.Width * MaxHeight / FullsizeImage.Height;
        //    NewHeight = MaxHeight;
        //}
        System.Drawing.Image NewImage = FullsizeImage.GetThumbnailImage(NewWidth, MaxHeight, null, IntPtr.Zero);
        // Clear handle to original file so that we can overwrite it if necessary
        FullsizeImage.Dispose();
        // Save resized picture

        if (fileExtension.ToLower() == ".jpg" || fileExtension.ToLower() == ".jpeg")
        {
            //NewImage.Save(NewFile, System.Drawing.Imaging.ImageFormat.Jpeg);

            Encoder quality = Encoder.Quality;
            var ratio = new EncoderParameter(quality, 100L);
            var codecParams = new EncoderParameters(1);
            codecParams.Param[0] = ratio;
            NewImage.Save(NewFile, GetEncoder(ImageFormat.Jpeg), codecParams);
        }

        if (fileExtension.ToLower() == ".png")
        {
            NewImage.Save(NewFile, System.Drawing.Imaging.ImageFormat.Png);
        }

        if (fileExtension.ToLower() == ".gif")
        {
            NewImage.Save(NewFile, System.Drawing.Imaging.ImageFormat.Gif);
        }
    }

ABOVE代码上传大图像并将其大小调整为400x264像素的固定大小。但是这种方法会延伸图像,因为我对维持宽高比的代码进行了评论。

重新调整大小的图像后,我允许用户使用jCrop选择此图像中的区域是350x230像素。

这没有任何问题,但图像被拉伸

protected void btnCrop_Command(object sender, CommandEventArgs e)
{
    cropImage();
    // pnlImageDetails.Visible = true;
}

protected void cropImage()
{
    var x = int.Parse(_xField.Value);
    var y = int.Parse(_yField.Value);
    var width = int.Parse(_widthField.Value);
    var height = int.Parse(_heightField.Value);
    string _CropImagePath = Session["_CropImagePath"].ToString();
    using (var photo = System.Drawing.Image.FromFile(_CropImagePath))
    using (var result =
          new Bitmap(width, height, photo.PixelFormat))
    {
        result.SetResolution(photo.HorizontalResolution, photo.VerticalResolution);
        using (var g = Graphics.FromImage(result))
        {
            // g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.DrawImage(photo, new Rectangle(0, 0, width, height),
                               new Rectangle(x, y, width, height),
                                             GraphicsUnit.Pixel);
            photo.Dispose();
            result.Save(_CropImagePath);
            string filePath = _CropImagePath.ToString();
            System.IO.FileInfo f = new System.IO.FileInfo(filePath);
            string fileExtension = f.Extension;
            string fileName = f.Name;
            string[] fNameArray = fileName.Split('.');
            string fileNewName = fNameArray[0] + "TN" + f.Extension;
            Session["ArticleThumbnailImage"] = fileNewName;
            string fileNewPath = Server.MapPath("../ImagesArticles/") + fileNewName;
            ResizeImageFreeSize(filePath, fileNewPath, 170, 112, true, fileExtension);
        }

    }
}

HTML代码的一部分

 <div id="ImageEditorFrame" style="width:800px; height:350px; float:left; ">

    <div style="width:404px; height:268px; margin-left:160px; margin-top:10px; padding-top:1px;  background-image:url('images/Scale.png'); background-repeat:no-repeat;">
        <div style="width:400px; height:264px; margin-left:3px; margin-top:2px; padding-top:1px; background-color:#f5f5f5;">
            <asp:Image runat="server" ID="_imageEditor" ImageUrl="" Visible="true" />   

        </div>
        <div style="margin-top:10px;"> 
         <asp:Button ID="btnCrop" runat="server" style="float:left;"  Text=" Crop Image " Visible="False" oncommand="btnCrop_Command"  />
        <input id="w" type="text" name="w" size="4" disabled="disabled">
        <input id="h" type="text" name="h" size="4" disabled="disabled">(350x230)<br /><br />
        <asp:Label ID="lblUplodedImgInfo" runat="server" Text=""></asp:Label>
        </div>
    </div>


    <input type="hidden" runat="server" id="_xField" />
    <input type="hidden" runat="server" id="_yField" />
    <input type="hidden" runat="server" id="_widthField" />
    <input type="hidden" runat="server" id="_heightField" />



</div>

var editorID = '<%= _imageEditor.ClientID %>';
jQuery(function () {
    jQuery('#' + editorID).Jcrop({
        onChange: showCoords,
        onSelect: showCoords,
        setSelect: [0, 0, 350, 230],
        allowResize: false
    });
});

function showCoords(c) {

    var xField = document.getElementById('<%= _xField.ClientID %>');
    var yField = document.getElementById('<%= _yField.ClientID %>');
    var widthField = document.getElementById('<%= _widthField.ClientID %>');
    var heightField = document.getElementById('<%= _heightField.ClientID %>');

    xField.value = c.x;
    yField.value = c.y;
    widthField.value = 350;
    heightField.value = 230;
    $('#w').val(c.w);
    $('#h').val(c.h);
}

屏幕截图的想法 Screen Shot for idea

我希望能够正确地为用户提供选择和图像区域的功能,并从中创建调整大小的图像。现在代码没有给出完美的结果。

如果有人可以帮我解决这个代码,我会很感激,我可以找到一个完整的工作示例。

此致

3 个答案:

答案 0 :(得分:1)

您可以维持图像尺寸的纵横比或硬限制,即400x264 如果要保持纵横比,调整后的图像应减少min(finalWidth/orignalWidth, finalHeight/orignalHeight)

答案 1 :(得分:1)

@MyItchyChin 我正在使用他的逻辑进行一些更改,所以我会将他的答案标记为正确** **

我编辑了这段代码,添加了两件事我因为锁定而得到错误所以我使用了MemoryStream来解决锁定问题。代码的另一个问题是它为JPG生成低分辨率图像,因为我添加了一些代码。其余的逻辑是相同的,我没有改变

public static void ResizeImageFreeSize(string OriginalFile, string NewFile, int MinWidth, int MinHeight, string FileExtension)
{
    var NewHeight = MinHeight;
    var NewWidth = MinWidth;
    // var OriginalImage = System.Drawing.Image.FromFile(OriginalFile); // THis statlement alon with generate error as file is locked so -->//GDI+ keeps a lock on files from which an image was contructed.  To avoid the lock, construct the image from a MemorySteam:

    MemoryStream ms = new MemoryStream(File.ReadAllBytes(OriginalFile));
    var OriginalImage = System.Drawing.Image.FromStream(ms);

    if (OriginalImage.Width < MinWidth || OriginalImage.Height < MinHeight)
        throw new Exception(String.Format("Invalid Image Dimensions, please upload an image with minmum dimensions of {0}x{1}px", MinWidth.ToString(), MinHeight.ToString()));

    // If the image dimensions are the same then make the new dimensions the largest of the two mins.
    if (OriginalImage.Height == OriginalImage.Width)
        NewWidth = NewHeight = (MinWidth > MinHeight) ? MinWidth : MinHeight;
    else
    {
        if (MinWidth > MinHeight)
            NewHeight = (int)(OriginalImage.Height * ((float)MinWidth / (float)OriginalImage.Width));
        else
            NewWidth = (int)(OriginalImage.Width * ((float)MinHeight / (float)OriginalImage.Height));
    }

    // Just resample the Original Image into a new Bitmap
    var ResizedBitmap = new System.Drawing.Bitmap(OriginalImage, NewWidth, NewHeight);

    // Saves the new bitmap in the same format as it's source image
    FileExtension = FileExtension.ToLower().Replace(".", "");

    ImageFormat Format = null;
    switch (FileExtension)
    {
        case "jpg":
            Format = ImageFormat.Jpeg;

            Encoder quality = Encoder.Quality;
            var ratio = new EncoderParameter(quality, 100L);
            var codecParams = new EncoderParameters(1);
            codecParams.Param[0] = ratio;
            // NewImage.Save(NewFile, GetEncoder(ImageFormat.Jpeg), codecParams);
            ResizedBitmap.Save(NewFile, GetEncoder(ImageFormat.Jpeg), codecParams);
            break;
        case "gif":
            Format = ImageFormat.Gif;
            ResizedBitmap.Save(NewFile, Format);
            break;
        case "png":
            Format = ImageFormat.Png;
            ResizedBitmap.Save(NewFile, Format);
            break;
        default:
            Format = ImageFormat.Png;
            ResizedBitmap.Save(NewFile, Format);
            break;
    }

    //  ResizedBitmap.Save(NewFile, Format);


    // Clear handle to original file so that we can overwrite it if necessary
    OriginalImage.Dispose();
    ResizedBitmap.Dispose();
}

private static ImageCodecInfo GetEncoder(ImageFormat format)
{
    ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
    foreach (ImageCodecInfo codec in codecs)
        if (codec.FormatID == format.Guid)
            return codec;
    return null;
}

答案 2 :(得分:0)

如果我理解正确,您的最终目标是最终得到一个350x230像素的缩略图,但您希望用户能够根据400x264px预览选择裁剪。不幸的是,你在预览时强制使用宽高比,这就是你得到失真的原因。如果您将400x264px维度视为最小值,则可以根据不会失真的分数生成缩略图。

public static void ResizeImageFreeSize(string OriginalFile, string NewFile, int MinWidth, int MinHeight, string FileExtension)
{
    var NewHeight = MinHeight;
    var NewWidth = MinWidth;        
    var OriginalImage = Image.FromFile(OriginalFile);

    if (OriginalImage.Width < MinWidth || OriginalImage.Height < MinHeight)
        throw new Exception(String.Format("Invalid Image Dimensions, please upload an image with minmum dimensions of {0}x{1}px", MinWidth.ToString(), MinHeight.ToString()));

    // If the image dimensions are the same then make the new dimensions the largest of the two mins.
    if (OriginalImage.Height == OriginalImage.Width)
        NewWidth = NewHeight = (MinWidth > MinHeight) ? MinWidth : MinHeight;
    else
    {
        if (MinWidth > MinHeight)
            NewHeight = (int)(OriginalImage.Height * ((float)MinWidth / (float)OriginalImage.Width));
        else
            NewWidth  = (int)(OriginalImage.Width * ((float)MinHeight / (float)OriginalImage.Height));
    }

    // Just resample the Original Image into a new Bitmap
    var ResizedBitmap = new System.Drawing.Bitmap(OriginalImage, NewWidth, NewHeight);

    // Saves the new bitmap in the same format as it's source image
    FileExtension = FileExtension.ToLower().Replace(".","");

    ImageFormat Format = null;
    switch (FileExtension)
    {
        case "jpg":
            Format = ImageFormat.Jpeg;
            break;
        case "gif":
            Format = ImageFormat.Gif;
            break;
        case "png":
            Format = ImageFormat.Png;
            break;
        default:
            Format = ImageFormat.Png;
            break;
    }

    ResizedBitmap.Save(NewFile, Format);


    // Clear handle to original file so that we can overwrite it if necessary
    OriginalImage.Dispose();
    ResizedBitmap.Dispose();
}