简体   繁体   English

C#非常简单的图像缩放器

[英]C# Very Simple Image Resizer

I am in need of a very simple c# image resizer. 我需要一个非常简单的c#图像缩放器。 By simple, I mean simple. 简单来说,我的意思很简单。 This is just a program that loops through a single directory and changes all the pictures in that directory to the same resolution. 这只是一个循环遍历单个目录并将该目录中的所有图片更改为相同分辨率的程序。 Here's what I have so far. 这是我到目前为止所拥有的。

        private void Form1_Load(object sender, EventArgs e)
    {
        string[] files = null;
        int count = 0;
        files = System.IO.Directory.GetFiles(@"C:\Users\..\..\ChristmasPicsResized");
        foreach (string file in files)
        {
            System.Drawing.Bitmap bmp = System.Drawing.Bipmap.FromFile(file);

            ResizeBitmap(bmp, 807, 605);
            bmp.Save(file);
            count++;
            lblCount.Text = count.ToString();
        }
    }
    public Bitmap ResizeBitmap(Bitmap b, int nWidth, int nHeight)
    {
        Bitmap result = new Bitmap(nWidth, nHeight);
        using (Graphics g = Graphics.FromImage((Image)result))
            g.DrawImage(b, 0, 0, nWidth, nHeight);
        return result;
    }

The problem I ran into is that the picture cannot be saved while it is open. 我遇到的问题是图片在打开时无法保存。 I am unsure how to make this into a file stream. 我不确定如何将其变成文件流。 What should be a very simple app doesn't seem so simple to me. 什么应该是一个非常简单的应用程序对我来说似乎并不那么简单。 Any help please? 有什么帮助吗?

尝试保存到临时文件,然后删除原始文件并将临时文件重命名为原始文件名。

Have a look at C# Image to Byte Array and Byte Array to Image Converter Class 看看C#Image to Byte Array和Byte Array to Image Converter Class

public byte[] imageToByteArray(System.Drawing.Image imageIn)
{
 MemoryStream ms = new MemoryStream();
 imageIn.Save(ms,System.Drawing.Imaging.ImageFormat.Gif);
 return  ms.ToArray();
}

and

public Image byteArrayToImage(byte[] byteArrayIn)
{
     MemoryStream ms = new MemoryStream(byteArrayIn);
     Image returnImage = Image.FromStream(ms);
     return returnImage;
}

This way you can close the image after you have read it in, and can then save it over the existing one. 这样,您就可以关闭图像,你已经读入后,然后可以将其保存现有的一个。

You could also render the resized images into a different folder to preserve the original, high-resolution images. 您还可以将调整大小的图像渲染到不同的文件夹中,以保留原始的高分辨率图像。 Maybe you'll need them one day (i did that mistake once...). 也许你有一天会需要它们(我曾经犯过那个错误......)。

I created this nuget package which does resizing for you: http://nuget.org/packages/Simple.ImageResizer 我创建了这个nuget包,它会为你调整大小: http ://nuget.org/packages/Simple.ImageResizer

Source and howto here: https://github.com/terjetyl/Simple.ImageResizer 来源和方法如下: https//github.com/terjetyl/Simple.ImageResizer

My C# Image Extension class: 我的C#Image Extension类:

namespace MycImageExtension
{
    public static class Helper
    {

        public static Image Clip(this Image imgPhoto, int width, int height)
        {
            return Clip(imgPhoto, width, height, false);
        }

        public static Image ToImage(this byte[] ba)
        {
            var ms = new MemoryStream(ba);
            return Image.FromStream(ms);
        }

        public static byte[] ToArray(this Image imgPhoto)
        {
            var ms = new MemoryStream();

        imgPhoto.Save(ms, ImageFormat.Jpeg);

            return ms.ToArray();
        }


        static ImageCodecInfo GetImageCodec(string mimetype)
        {
            foreach (ImageCodecInfo ici in ImageCodecInfo.GetImageEncoders())
            {
                if (ici.MimeType == mimetype) return ici;
            }
            return null;
        }




        public static Image Clip(this Image imgPhoto, int width, int height, bool stretch)
        {
            if (!stretch && (imgPhoto.Width <= width && imgPhoto.Height <= height))
                return imgPhoto;


            // detect if portrait
            if (imgPhoto.Height > imgPhoto.Width)
            {
                // swap
                int a = width;
                width = height;
                height = a;
            }


            var d = new Dimension(imgPhoto.Width, imgPhoto.Height);
            double scale = d.NewSizeScaleFactor(new Dimension(width, height), stretch);

            var newD = scale * d;


            if (stretch)
            {            
                if (!(newD.Width == width || newD.Height == height))
                    throw new Exception("Stretching algo has some error");
            }




            var bmPhoto = new Bitmap(imgPhoto, new Size(newD.Width, newD.Height));

            return bmPhoto;
        }




        // using for crystal report
        public static Image PadImage(this Image imgPhoto, int width, int height)
        {
            // detect if portrait
            if (imgPhoto.Height > imgPhoto.Width)
            {
                // swap
                int a = width;
                width = height;
                height = a;
            }

            var d = new Dimension(imgPhoto.Width, imgPhoto.Height);
            double scale = d.NewSizeScaleFactor(new Dimension(width, height), true);

            Dimension newSize = scale * d;


            PadAt padAt;
            int padNeeded;
            newSize.GetPadNeeded(new Dimension(width, height), out padAt, out padNeeded);


            int padLeft = 0, padTop = 0;

            if (padAt == PadAt.Width)
                padLeft = padNeeded;
            else if (padAt == PadAt.Height)
                padTop = padNeeded;



            var bmPhoto = new Bitmap(width, height, PixelFormat.Format24bppRgb);



            var grPhoto = Graphics.FromImage(bmPhoto);
            grPhoto.Clear(Color.White);

            grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;

            grPhoto.DrawImage(imgPhoto,
                new Rectangle(padLeft, padTop, newSize.Width, newSize.Height),
                new Rectangle(0, 0, imgPhoto.Width, imgPhoto.Height),
                GraphicsUnit.Pixel);

            grPhoto.Dispose();

            return bmPhoto;

        }


    }







    public enum PadAt { None = 0, Width = 1, Height }


    public struct Dimension
    {
        public int Width { set; get; }
        public int Height { set; get; }



        public Dimension(int width, int height)
            : this()
        {
            this.Width = width;
            this.Height = height;
        }

        public override string ToString()
        {
            return string.Format("Width: {0} Height: {1}", Width, Height);
        }



        public static Dimension operator *(Dimension src, double scale)
        {
            return new Dimension((int)Math.Ceiling((scale * src.Width)), (int)Math.Ceiling((scale * src.Height)));
        }


        public static Dimension operator *(double scale, Dimension src)
        {
            return new Dimension((int)Math.Ceiling((scale * src.Width)), (int)Math.Ceiling((scale * src.Height)));
        }


        public double NewSizeScaleFactor(Dimension newSize, bool stretch)
        {


            if (!stretch
                &&

                (this.Width <= newSize.Width && this.Height <= newSize.Height))

                return 1;


            double widthScaleFactor = (double)newSize.Width / this.Width;
            double heightScaleFactor = (double)newSize.Height / this.Height;



            // return the lowest scale factor

            if (widthScaleFactor < heightScaleFactor)
                return widthScaleFactor;
            else if (heightScaleFactor < widthScaleFactor)
                return heightScaleFactor;
            else
                return widthScaleFactor; // can even use heightscalefactor
        }


        public Dimension Clip(Dimension newSize, bool stretch)
        {
            if (!stretch
                &&

                (this.Width <= newSize.Width && this.Height <= newSize.Height))

                return new Dimension(this.Width, this.Height);



            double smallestScaleFactor = NewSizeScaleFactor(newSize, stretch);


            return new Dimension((int)(this.Width * smallestScaleFactor), (int)(this.Height * smallestScaleFactor));
        }




        // so crystal report images would have exact dimension
        public void GetPadNeeded(Dimension newSize, out PadAt padAt, out int padNeeded)
        {

            if (this.Width == newSize.Width && this.Height == newSize.Height)
            {
                padAt = PadAt.None;
                padNeeded = 0;
                return;
            }



            if (this.Width > newSize.Width || this.Height > newSize.Height)
                throw new Exception("Source cannot be bigger than the new size");


            if (this.Width != newSize.Width && this.Height != newSize.Height)
                throw new Exception("At least one side should be equal");


            if (newSize.Width != this.Width)
            {
                padAt = PadAt.Width;
                padNeeded = (newSize.Width - this.Width) / 2;
            }
            else if (newSize.Height != this.Width)
            {
                padAt = PadAt.Height;
                padNeeded = (newSize.Height - this.Height) / 2;
            }
            else
            {
                throw new Exception("Some anomaly occured, contact the programmer");
            }

        }


        // test the logic   

        static void X()
        {

            var ls = new Dimension[]
            {
                new Dimension(400, 400), // as is
                new Dimension(640, 480), // as is
                new Dimension(600, 480), // as is
                new Dimension(800, 600), // as is
                new Dimension(800, 400), // as is
                new Dimension(1280, 960), // as is
                new Dimension(1280, 961), // as is
                new Dimension(1281, 960), // as is
                new Dimension(1280, 900), // as is
                new Dimension(1000, 960), // as is
                new Dimension(1000, 970), // as is
                new Dimension(1000, 900), // as is

                new Dimension(1380, 960), // clip
                new Dimension(1280, 1000), // clip

                new Dimension(1380, 1300), // clip

                new Dimension(1600, 1200), // clip
                new Dimension(1600, 1000), // clip
                new Dimension(1800, 1200), // clip
                new Dimension(1800, 1000), // clip
                new Dimension(1400, 1200), // clip
                new Dimension(1400, 1000), // clip
                new Dimension(960, 1280), // clip
                new Dimension(960, 1300), // clip
                new Dimension(970, 1280) // clip
            };





            foreach (var l in ls)
            {

                // saving to database...
                double scale = l.NewSizeScaleFactor(new Dimension(1280, 960), false);
                Dimension newSize = scale * l;
                // ...saving to database




                // display to crystal report...
                double scaleA = l.NewSizeScaleFactor(new Dimension(800, 600), true);
                Dimension newSizeA = scaleA * l;



                PadAt padAt;
                int padNeeded;
                newSizeA.GetPadNeeded(new Dimension(800, 600), out padAt, out padNeeded);

                // ...display to crystal report

                Console.WriteLine("Pad {0} {1}", padAt, padNeeded);

                Console.WriteLine();


            }

            Console.ReadLine();
        }





    }


}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM