繁体   English   中英

如何迭代.gif图像中的每个像素?

[英]How can I iterate through each pixel in a .gif image?

我需要逐步浏览.gif图像并确定每个像素的RGB值,x和y坐标。 有人能给我一个如何实现这个目标的概述吗? (方法,要使用的命名空间等)

这是使用LockBits()和GetPixel()的两种方法的完整示例。 除了LockBits()的信任问题,事情很容易变得毛茸茸。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace BitmapReader
{
    class Program
    {
        static void Main(string[] args)
        {
            //Try a small pic to be able to compare output, 
            //a big one to compare performance
            System.Drawing.Bitmap b = new 
                System.Drawing.Bitmap(@"C:\Users\vinko\Pictures\Dibujo2.jpg"); 
            doSomethingWithBitmapSlow(b);
            doSomethingWithBitmapFast(b);
        }

        public static void doSomethingWithBitmapSlow(System.Drawing.Bitmap bmp)
        {
            for (int x = 0; x < bmp.Width; x++)
            {
                for (int y = 0; y < bmp.Height; y++)
                {
                    Color clr = bmp.GetPixel(x, y);
                    int red = clr.R;
                    int green = clr.G;
                    int blue = clr.B;
                    Console.WriteLine("Slow: " + red + " " 
                                       + green + " " + blue);
                }
            }
        }

        public static void doSomethingWithBitmapFast(System.Drawing.Bitmap bmp)
        {
            Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);

            System.Drawing.Imaging.BitmapData bmpData =
                bmp.LockBits(rect, 
                    System.Drawing.Imaging.ImageLockMode.ReadOnly,
                    bmp.PixelFormat);

            IntPtr ptr = bmpData.Scan0;

            int bytes = bmpData.Stride * bmp.Height;
            byte[] rgbValues = new byte[bytes];

            System.Runtime.InteropServices.Marshal.Copy(ptr, 
                           rgbValues, 0, bytes);

            byte red = 0;
            byte green = 0;
            byte blue = 0;

            for (int x = 0; x < bmp.Width; x++)
            {
                for (int y = 0; y < bmp.Height; y++)
                {
                    //See the link above for an explanation 
                    //of this calculation
                    int position = (y * bmpData.Stride) + (x * Image.GetPixelFormatSize(bmpData.PixelFormat)/8); 
                    blue = rgbValues[position];
                    green = rgbValues[position + 1];
                    red = rgbValues[position + 2];
                    Console.WriteLine("Fast: " + red + " " 
                                       + green + " " + blue);
                }
            }
            bmp.UnlockBits(bmpData);
        }
    }
}

您可以使用new Bitmap(filename)加载图像,然后重复使用Bitmap.GetPixel 这很慢但很简单。 (请参阅Vinko的答案。)

如果性能很重要,您可能需要使用Bitmap.LockBits和不安全的代码。 显然,这降低了多少地方你可以使用该解决方案(在信任度方面)和一般比较复杂-但它可以是快了很多

如果你的gif没有动画,请使用:

Image img = Image.FromFile("image.gif");

for (int x = 0; x < img.Width; x++)
{
    for (int y = 0; y < img.Height; y++)
    {
        // Do stuff here
    }
}

(未测试)


否则使用它来遍历所有帧,以及:

Image img = Image.FromFile("animation.gif");

FrameDimension frameDimension = new FrameDimension(img.FrameDimensionsList[0]);
int frames = img.GetFrameCount(frameDimension);

for (int f = 0; f < frames; f++)
{
    img.SelectActiveFrame(frameDimension, f);

    for (int x = 0; x < img.Width; x++)
    {
        for (int y = 0; y < img.Height; y++)
        {
            // Do stuff here
        }
    }
}

(未测试)

暂无
暂无

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

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