将图像大小调整为 2x2 像素为 4x4 像素,保持颜色相同

发布于 2025-01-02 12:20:58 字数 7261 浏览 0 评论 0原文

请想象我有一个非常简单的棋盘图像。

在这里,我用字母表示图像作为像素:黑色像素“B”,白色像素“W”

这是起始的 2x2 像素图像:

BW
WB

我想调整图像大小,可以说按 2x 的比例给我:

BBWW
BBWW
WWBB
WWBB

或比例 4x

BBBBWWWW
BBBBWWWW
WWWWBBBB
WWWWBBBB

所以像素颜色根本不会以任何方式抖动。

我已经在 C# 中尝试过了,但图像一团糟,全部抖动,我需要学习如何在不抖动/颜色变化的情况下做到这一点。

到目前为止,这是我的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Text;

namespace PageTwine
{
    public partial class RandonGiff : System.Web.UI.Page
    {


        protected void Page_Load(object sender, EventArgs e)
        {

            // create 2x2 chequerboard:
            Bitmap oBitmap = new Bitmap(2, 2);
            Graphics oGraphic = Graphics.FromImage(oBitmap);

            // color black pixels (i think the default is black but this helps to explain)
            SolidBrush oBrush = new SolidBrush(Color.FromArgb(255, 255, 255));
            oGraphic.FillRectangle(oBrush, 0, 0, 1, 1);
            oGraphic.FillRectangle(oBrush, 1, 1, 1, 1);

            //color white pixels
            oBrush = new SolidBrush(Color.FromArgb(0, 0, 0));
            oGraphic.FillRectangle(oBrush, 0, 1, 1, 1);
            oGraphic.FillRectangle(oBrush, 1, 0, 1, 1);

            // expand to 4x4
            Bitmap result = new Bitmap(4, 4);
            using (Graphics graphics = Graphics.FromImage(result))
            {
                // I don't know what these settings should be :

                graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
                graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;

                //draw the image into the target bitmap 
                graphics.DrawImage(oBitmap, 0, 0, result.Width, result.Height);
            }

            //send image directly to the browser
            Response.ContentType = "image/gif";
            result.Save(Response.OutputStream, ImageFormat.Gif);

        }
    }

}

结果是抖动图像,但我需要干净清晰的棋盘效果。 请你帮帮我。

编辑:07/02/12

感谢到目前为止的建议,但我仍在搜索但没有找到解决方案。

我创建了一个演示页面,以便您可以亲自查看结果。

演示的 URL 为:

http://www. Leansoftware.net/servicedesk/publicadhoc/randomgif.aspx?columns=3&rows=3

该演示将创建一个棋盘格,其中初始列 x 行作为像素,然后放大为 300x300 像素的 gif 图像。

你会看到颜色扭曲/有点小——这是我试图解决的问题。

以下是演示的源代码:

using System;
using System.Collections.Generic;
using System.Web;
using System.IO;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.Linq;


    public partial class RandomGif : System.Web.UI.Page
    {
        public class Coordinates
        {
            public int x { get; set; }
            public int y { get; set; }
        }

        static Random rand = new Random();

        protected void Page_Load(object sender, EventArgs e)
        {
            // Output type gif
            int iwidth;
            int iheight;
            int bits;
            Response.ContentType = "image/gif";

            // Get parameters
            if (Request.QueryString["count"] != null)
            {
                bits = Convert.ToInt32(Request.QueryString["count"]);
                int square = Convert.ToInt32(Math.Ceiling(Math.Sqrt(bits + Math.Floor(bits / 4.0))));
                iwidth = square;
                iheight = square;
                bits = (square * square)-1;
            }
            else
                if (Request.QueryString["rows"] != null && Request.QueryString["columns"] != null)
                {
                    iwidth = Convert.ToInt32(Request.QueryString["columns"]);
                    iheight = Convert.ToInt32(Request.QueryString["rows"]);
                    bits = (iwidth * iheight);
                }
                else {
                    return;
                }
        if (bits > 1000){
        Response.Write("Please specify a grid <= 1000 pixels");
        return;
        }

            int plotCount = 0;

            //web safe colors : 00, 33, 66, 99, CC, FF;
            List<int> webSafeColor = new List<int>();
            webSafeColor.Add(0); //00
            webSafeColor.Add(51);//33
            webSafeColor.Add(102);//66
            webSafeColor.Add(153);//99
            webSafeColor.Add(204);//CC
            webSafeColor.Add(255);//FF

            // Create a structure to hold all possible coordinates
            var Grid = new List<Coordinates>();
            for (int xi = 1; xi <= iwidth; xi++)
            {
                for (int yi = 1; yi <= iheight; yi++)
                {
                    Grid.Add(new Coordinates { x = xi, y = yi });
                    plotCount++;
                }
            }

            //create a new Bitmap object
            Bitmap oBitmap = new Bitmap(iwidth, iheight);

            //create a new Graphics object, which will allow us to draw on our bitmap:
            Graphics oGraphic = Graphics.FromImage(oBitmap);


            //fill the image rectangle with n bits
            for (int i = 1; i <= bits; i++)
            {
                //Random rand = new Random();
                int row = rand.Next(Grid.Count());

                // random red
                int ircolor = webSafeColor[rand.Next(5)];

                // random green
                int igcolor = webSafeColor[rand.Next(5)];

                // random blue
                int ibcolor = webSafeColor[rand.Next(5)];

                Color randomColor = Color.FromArgb(ircolor, igcolor, ibcolor);
                SolidBrush oBrush = new SolidBrush(randomColor);
                oGraphic.FillRectangle(oBrush, Grid[row].x - 1, Grid[row].y - 1, 1, 1);

        // Delete this coordinate#
                Grid.Remove(Grid[row]);
            }

            // resize image
            Bitmap result = new Bitmap(300, 300);
            using (Graphics graphics = Graphics.FromImage(result))
            {
                //set the resize quality modes to high quality 
                graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.AssumeLinear;
                graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
                graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half; 

                //draw the image into the target bitmap 
                graphics.DrawImage(oBitmap, 0, 0, result.Width, result.Height);
            }

            //send image directly to the browser
            Response.ContentType = "image/gif";
            result.Save(Response.OutputStream, ImageFormat.Gif);

        }
    }

如果您可以提出修改建议,我们可以尝试一下,看看是否可以解决问题。

谢谢理查德

Please imagine I have a very simple chequerboard image.

Here I represent the image with letters as pixels: black pixel 'B', white pixel 'W'

Here is the starting 2x2 pixel image:

BW
WB

I want to resize the image, lets say by scale of 2x to give me :

BBWW
BBWW
WWBB
WWBB

or scale 4x

BBBBWWWW
BBBBWWWW
WWWWBBBB
WWWWBBBB

So that the pixel colours are not dithered in any way at all.

I have tried this in C# but the image is a mess, all dithered, I need to learn how to do this without dithering/color change.

Here is my code so far:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Text;

namespace PageTwine
{
    public partial class RandonGiff : System.Web.UI.Page
    {


        protected void Page_Load(object sender, EventArgs e)
        {

            // create 2x2 chequerboard:
            Bitmap oBitmap = new Bitmap(2, 2);
            Graphics oGraphic = Graphics.FromImage(oBitmap);

            // color black pixels (i think the default is black but this helps to explain)
            SolidBrush oBrush = new SolidBrush(Color.FromArgb(255, 255, 255));
            oGraphic.FillRectangle(oBrush, 0, 0, 1, 1);
            oGraphic.FillRectangle(oBrush, 1, 1, 1, 1);

            //color white pixels
            oBrush = new SolidBrush(Color.FromArgb(0, 0, 0));
            oGraphic.FillRectangle(oBrush, 0, 1, 1, 1);
            oGraphic.FillRectangle(oBrush, 1, 0, 1, 1);

            // expand to 4x4
            Bitmap result = new Bitmap(4, 4);
            using (Graphics graphics = Graphics.FromImage(result))
            {
                // I don't know what these settings should be :

                graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
                graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;

                //draw the image into the target bitmap 
                graphics.DrawImage(oBitmap, 0, 0, result.Width, result.Height);
            }

            //send image directly to the browser
            Response.ContentType = "image/gif";
            result.Save(Response.OutputStream, ImageFormat.Gif);

        }
    }

}

The result is a dithered image, but I need a clean crisp chequerboard effect.
Please can you help me.

EDIT:07/02/12

Thanks for the suggestions so far but I am still searching without finding a solution.

I have created a demo page so you can see the results for yourself.

The URL for the demo is :

http://www.leansoftware.net/servicedesk/publicadhoc/randomgif.aspx?columns=3&rows=3

The demo will create a chequerboard with initial columns x rows as pixels, then enlarge to a gif image 300x300 px.

You will see that colours are distorted/bitty - this I am trying to solve.

Here is the source code for the demo:

using System;
using System.Collections.Generic;
using System.Web;
using System.IO;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.Linq;


    public partial class RandomGif : System.Web.UI.Page
    {
        public class Coordinates
        {
            public int x { get; set; }
            public int y { get; set; }
        }

        static Random rand = new Random();

        protected void Page_Load(object sender, EventArgs e)
        {
            // Output type gif
            int iwidth;
            int iheight;
            int bits;
            Response.ContentType = "image/gif";

            // Get parameters
            if (Request.QueryString["count"] != null)
            {
                bits = Convert.ToInt32(Request.QueryString["count"]);
                int square = Convert.ToInt32(Math.Ceiling(Math.Sqrt(bits + Math.Floor(bits / 4.0))));
                iwidth = square;
                iheight = square;
                bits = (square * square)-1;
            }
            else
                if (Request.QueryString["rows"] != null && Request.QueryString["columns"] != null)
                {
                    iwidth = Convert.ToInt32(Request.QueryString["columns"]);
                    iheight = Convert.ToInt32(Request.QueryString["rows"]);
                    bits = (iwidth * iheight);
                }
                else {
                    return;
                }
        if (bits > 1000){
        Response.Write("Please specify a grid <= 1000 pixels");
        return;
        }

            int plotCount = 0;

            //web safe colors : 00, 33, 66, 99, CC, FF;
            List<int> webSafeColor = new List<int>();
            webSafeColor.Add(0); //00
            webSafeColor.Add(51);//33
            webSafeColor.Add(102);//66
            webSafeColor.Add(153);//99
            webSafeColor.Add(204);//CC
            webSafeColor.Add(255);//FF

            // Create a structure to hold all possible coordinates
            var Grid = new List<Coordinates>();
            for (int xi = 1; xi <= iwidth; xi++)
            {
                for (int yi = 1; yi <= iheight; yi++)
                {
                    Grid.Add(new Coordinates { x = xi, y = yi });
                    plotCount++;
                }
            }

            //create a new Bitmap object
            Bitmap oBitmap = new Bitmap(iwidth, iheight);

            //create a new Graphics object, which will allow us to draw on our bitmap:
            Graphics oGraphic = Graphics.FromImage(oBitmap);


            //fill the image rectangle with n bits
            for (int i = 1; i <= bits; i++)
            {
                //Random rand = new Random();
                int row = rand.Next(Grid.Count());

                // random red
                int ircolor = webSafeColor[rand.Next(5)];

                // random green
                int igcolor = webSafeColor[rand.Next(5)];

                // random blue
                int ibcolor = webSafeColor[rand.Next(5)];

                Color randomColor = Color.FromArgb(ircolor, igcolor, ibcolor);
                SolidBrush oBrush = new SolidBrush(randomColor);
                oGraphic.FillRectangle(oBrush, Grid[row].x - 1, Grid[row].y - 1, 1, 1);

        // Delete this coordinate#
                Grid.Remove(Grid[row]);
            }

            // resize image
            Bitmap result = new Bitmap(300, 300);
            using (Graphics graphics = Graphics.FromImage(result))
            {
                //set the resize quality modes to high quality 
                graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.AssumeLinear;
                graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
                graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half; 

                //draw the image into the target bitmap 
                graphics.DrawImage(oBitmap, 0, 0, result.Width, result.Height);
            }

            //send image directly to the browser
            Response.ContentType = "image/gif";
            result.Save(Response.OutputStream, ImageFormat.Gif);

        }
    }

If you can suggest modifications we can try them out and see if it fixes the problem.

Thanks Richard

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦里兽 2025-01-09 12:20:58

这可能是 c# Draw 的重复项图像(缩放)到图形无法正确插值。修复?

您需要添加:

graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;

或者,您可以使用

graphics.DrawImage(oBitmap, 0, 0, result.Width * 2, result.Height * 2);

强制画笔填充而不会在右下图像边缘扭曲的情况下实现类似的效果。

更新:

添加用于使用自定义调色板创建索引图像的链接。
http://support.microsoft.com/kb/319061

This is a possible duplicate of c# Draw Image (Scaled) to Graphics, does not interpolate correctly. Fixes?

You need to add:

graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;

Alternately, you could use

graphics.DrawImage(oBitmap, 0, 0, result.Width * 2, result.Height * 2);

to achieve a similar effect of forcing the brush to fill without warping at the right-bottom image edges.

Update:

Adding link for creating indexed images with a custom color palette.
http://support.microsoft.com/kb/319061

暗藏城府 2025-01-09 12:20:58

使用:

System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;

Use:

System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文