1

私はウェブサイトをデザインしていますが、アスペクト比を失うことなく、大きな画像のサイズを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);
        }
    }

上記のコードは大きな画像をアップロードし、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);
}

アイデアのスクリーンショット アイデアのスクリーンショット

画像の領域を選択してその領域からサイズ変更された画像を作成する機能をユーザーに提供できる場所で、それを正しく実現したいと思います。現在、コードは完璧な結果をもたらしていません。

誰かがこのコードで私を助けてくれれば、完全な実例を教えていただければ幸いです。

よろしく

4

3 に答える 3

1

@MyItchyChin私は彼のロジックをいくつか変更して使用しているので、彼の答えも正しいとマークします**

このコードを編集して、ロックが原因でエラーが発生した2つのものを追加したので、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;
}
于 2012-04-26T07:57:07.667 に答える
1

アスペクト比を維持するか、画像のサイズに厳しい制限を設けることができます。つまり、400x264アスペクト比を維持したい場合は、サイズ変更された画像を次の係数で縮小する必要があります。 min(finalWidth/orignalWidth, finalHeight/orignalHeight)

見る

于 2012-04-25T13:37:36.613 に答える
0

私が正しく理解していれば、最終的な目標は350x230pxのサムネイル画像になることですが、ユーザーが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();
}
于 2012-04-25T22:43:14.777 に答える