计算机如何调整图像大小?

3

图像调整大小在任何GUI框架中几乎是普遍的。事实上,在Web开发中刚开始学习时,你学习的第一件事情之一就是如何使用CSS或HTML的img属性缩放图像。但它是如何工作的呢?

当我要求计算机将一个500x500的图像缩放为100x50,或者相反地,计算机如何知道从原始图像中绘制哪些像素呢?最后,我是否可以用其他编程语言编写自己的“图像转换器”,而不会显著降低性能?


4
https://en.wikipedia.org/wiki/Image_scaling - Kaiido
维基百科的文章在涉及到现代浏览器使用的实际技术时...并不是很令人兴奋。查看这个链接,似乎有几个自定义算法被使用,需要进一步研究。 - Ramneek Singh
是的,作为作者,您甚至可以控制使用哪些算法:对于光栅图像对于矢量图像 - Kaiido
1个回答

0

根据一些研究,我可以得出结论,大多数网络浏览器将使用最近邻或线性插值进行图像调整大小。我编写了一个概念上的最近邻算法,成功地调整了图像大小,尽管非常缓慢。

using System;
using System.Drawing;
using System.Timers;

namespace Image_Resize
{
    class ImageResizer
    {
        public static Image Resize(Image baseImage, int newHeight, int newWidth)
        {
            var baseBitmap = new Bitmap(baseImage);
            int baseHeight = baseBitmap.Height;
            int baseWidth = baseBitmap.Width;

            //Nearest neighbor interpolation converts pixels in the resized image to pixels closest to the old image. We have a 2x2 image, and want to make it a 9x9.
            //Step 1. Take a 9x9 image and shrink it back to old value. To do this, divide the new width by old width (i.e. 9/2 = 4.5)
            float widthRatio = (float)baseWidth/newWidth;
            float heightRatio = (float)baseHeight/newHeight;

            //Step 2. Perform an integer comparison for each pixel in old I believe. If we have a pixel in the new located at (4,5), then the proportional will be
            //(.8888, 1.11111) which SHOULD GO DOWN to (0,1) coordinates on a 2x2. Seems counter intuitive, but imagining a 2x2 grid, (4.5) is on the left-bottom coordinate
            //so it makes sense the to be on the (0,1) pixel.


            var watch = new System.Diagnostics.Stopwatch();
            watch.Start();
            Bitmap resized = new Bitmap(newWidth, newHeight);
            int oldX = 0; int oldY = 0;
            for (int i = 0; i < newWidth; i++)
            {
                oldX = (int)(i*widthRatio);
                for (int j = 0; j < newHeight; j++)
                {
                    oldY = (int)(j*heightRatio);
                    Color newColor = baseBitmap.GetPixel(oldX,oldY);
                    resized.SetPixel(i,j, newColor);
                }

            }

            //This works, but is 100x slower than standard library methods due to GetPixel() and SetPixel() methods. The average time to set a 1920x1080 image is a second.
            watch.Stop();
            Console.WriteLine("Resizing the image took " + watch.Elapsed.TotalMilliseconds + "ms.");
            return resized;

        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var img = Image.FromFile(@"C:\Users\kpsin\Pictures\codeimage.jpg");
            img = ImageResizer.Resize(img, 1000, 1500);
            img.Save(@"C:\Users\kpsin\Pictures\codeimage1.jpg");
        }
    }
}


我真的希望有人能提供一种更快的最近邻算法,因为我可能忽略了一些愚蠢的东西;或者提供另一种我不知道的图像缩放工作方式。否则,这个问题就解决了吗?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接