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

时间:2012-02-03 23:28:04

标签: c# image resize

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

这里我用字母表示像素的图像:黑色像素“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

演示将创建一个chequerboard,初始列x行作为像素,然后放大到gif图像300x300 px。

你会看到颜色扭曲/有点 - 我想解决这个问题。

以下是演示的源代码:

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);

        }
    }

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

谢谢理查德

2 个答案:

答案 0 :(得分:2)

这可能是c# Draw Image (Scaled) to Graphics, does not interpolate correctly. Fixes?

的副本

您需要添加:

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

或者,您可以使用

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

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

更新:

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

答案 1 :(得分:0)

使用:

System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;