创建闪亮的图形/光泽效果

时间:2020-03-06 14:29:45  来源:igfitidea点击:

我想以编程方式在Image上创建光泽效果,就像在Web更新到2.0 Beta时采用的Apple启发设计一样。

本质上是这样的:

示例图标http://nhc.hcmuns.googlepages.com/web2_icons.jpg

现在,我在这里看到两种方法:我创建一个具有带有光泽效果的Alpha通道的图像,然后将输入和光泽Alpha图标组合在一起来创建此图像。

第二种方法:用代码创建Alpha Gloss Image,然后将其与输入图形合并。

我希望使用第二种解决方案,但我不是图形专家,也不知道创建这种效果的算法是什么。有人可以给我一些指向我在这里实际寻找的东西吗?有没有名称的"光泽算法"?甚至是.net实现?

*不,不是那些类型的指针。

解决方案

我可以用图形的方式解释这种效果。

  • 创建一个图标大小的3倍左右的图像。
  • 在此图像内,创建一个圆圈,其中(图标的高度)<半径<2 *(图标的高度)。
  • 用例如10%的alpha混合/透明度(至白色)填充圆圈。
  • 将圆圈图像裁剪为与图标大小相同的新图像,其中圆圈的中心位于查看区域的外部,但向上移至较小图像高度的1/2.

然后,如果将此图像叠加到原始图标上,则效果应大致类似于上述图标。如果我们热衷于此,可以使用imagemagick进行操作,也可以根据要使用的语言来选择其中一种图形API。从上述步骤开始,以编程方式进行操作应该很简单。

谢谢,德文!这是我的CCode,用于实现建议。效果很好。将其变成社区拥有的Wiki帖子,如果有人喜欢添加一些代码,请随时进行编辑。

(示例使用的Alpha和Exposure值与下面的代码不同)

Image img = Image.FromFile("rss-icon.jpg");
pictureBox1.Image = AddCircularGloss(img, 30,25,255,255,255);

public static Image AddCircularGloss(Image inputImage, int exposurePercentage, int transparency, int fillColorR, int fillColorG, int fillColorB)
{
    Bitmap outputImage = new Bitmap(inputImage);
    using (Graphics g = Graphics.FromImage(outputImage))
    {
        using (Pen p = new Pen(Color.FromArgb(transparency, fillColorR, fillColorG, fillColorB)))
        {
            // Looks jaggy otherwise
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.CompositingQuality = CompositingQuality.HighQuality;
            int x, y;

            // 3 * Height looks best
            int diameter = outputImage.Height * 3;
            double imgPercent = (double)outputImage.Height / 100;
            x = 0 - outputImage.Width;

            // How many percent of the image to expose
            y = (0 - diameter) + (int)(imgPercent * exposurePercentage);
            g.FillEllipse(p.Brush, x, y, diameter, diameter);
        }
    }
    return outputImage;
}

(在约翰的建议之后更改。尽管我无法处理位图,但这必须由函数的调用者完成)

响应Ccode ...总的来说,在推动图像处理方面做得很好。过去,我不得不对某些应用做类似的事情。

但是,有一条建议:.NET中的所有图形对象都基于Windows GDI +基元。这意味着这些对象需要正确处理以清理其非内存资源,就像文件句柄或者数据库连接一样。我们需要稍微调整一下代码以正确地支持它。

所有GDI +对象都实现IDisposable接口,从而使它们可以通过using语句使用。考虑类似于以下内容重写代码:

// Experiment with this value
int exposurePercentage = 40;

using (Image img = Image.FromFile("rss-icon.jpg"))
{
    using (Graphics g = Graphics.FromImage(img))
    {    
        // First Number = Alpha, Experiment with this value.
        using (Pen p = new Pen(Color.FromArgb(75, 255, 255, 255)))
        {
            // Looks jaggy otherwise
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            int x, y;

            // 3 * Height looks best
            int diameter = img.Height * 3;
            double imgPercent = (double)img.Height / 100;
            x = 0 - img.Width;

            // How many percent of the image to expose
            y = (0 - diameter) + (int)(imgPercent * exposurePercentage);

            g.FillEllipse(p.Brush, x, y, diameter, diameter);

            pictureBox1.Image = img;
        }
    }
}

(请记住,与我的大多数示例不同,我没有机会进行编译和测试。。。这更多是作为结构化代码的示例,以确保没有资源泄漏,而不是作为最终产品。无论如何,可能都有更好的抽象/结构化方法,并强烈考虑这样做-在图形库DLL中扔这个,我们可以在将来需要这些功能的任何项目中引用它!)