首页 新闻 会员 周边 捐助

C# GDI+ 图像局部变形

0
悬赏园豆:10 [已解决问题] 解决于 2010-08-28 22:25

 当图像比目标形状小的时候, 扩大图像适应目标形状。

 当图像比目标形状大的时候, 缩小图像适应目标形状。

问题补充: 呵呵 谢谢 目标形状是一个不规则的形状如圆或者多边形 我想要的效果是图像完全填充目标形状,而图像不能只截取部分
.zZ的主页 .zZ | 菜鸟二级 | 园豆:225
提问于:2010-08-27 16:57
< >
分享
最佳答案
0

DrawImage 时按照目标形状给定矩形框大小即可,下面是MSDN上的代码:

Bitmap myBitmap = new Bitmap("Spiral.png");

Rectangle expansionRectangle
= new Rectangle(135, 10,
myBitmap.Width, myBitmap.Height);

Rectangle compressionRectangle
= new Rectangle(300, 10,
myBitmap.Width
/ 2, myBitmap.Height / 2);

myGraphics.DrawImage(myBitmap,
10, 10);
myGraphics.DrawImage(myBitmap, expansionRectangle);
myGraphics.DrawImage(myBitmap, compressionRectangle);

 

 

 

以上图形转换的代码如下,经测试通过,参考了CxImage的源码:

 

 

static int ComputePixel(float x, float y, out float x1, out float y1)
{
double r, nn;

if (x == 0 && y == 0)
{
x1
= x;
y1
= y;
return 1;
}

nn
= Math.Sqrt(x * x + y * y);
r
= (Math.Abs(x) > Math.Abs(y)) ? Math.Abs(nn / x) : Math.Abs(nn / y);

x1
= (float)(r * x);
y1
= (float)(r * y);

return 1;
}

static Color GetPixelColorInterpolated(ref Bitmap image, float x, float y)
{
int xi = (int)(x);
if (x < 0) xi--;
int yi = (int)(y);
if (y < 0) yi--;

if (xi < -1 || xi >= image.Width || yi < -1 || yi >= image.Height)
{
return GetPixelColorWithOverflow(ref image, -999, -999);
}

//get four neighbouring pixels
if ((xi + 1) < image.Width && xi >= 0 && (yi + 1) < image.Height && yi >= 0)
{
ushort wt1 = (ushort)((x - xi) * 256.0f), wt2 = (ushort)((y - yi) * 256.0f);
ushort wd = (ushort)(wt1 * wt2 >> 8);
ushort wb = (ushort)(wt1 - wd);
ushort wc = (ushort)(wt2 - wd);
ushort wa = (ushort)(256 - wt1 - wc);
ushort wrr, wgg, wbb;

Color clr
= image.GetPixel(xi, yi);
wbb
= (ushort)(wa * clr.B); wgg = (ushort)(wa * clr.G); wrr = (ushort)(wa * clr.R);

clr
= image.GetPixel(xi + 1, yi);
wbb
+= (ushort)(wb * clr.B); wgg += (ushort)(wb * clr.G); wrr += (ushort)(wb * clr.R);

clr
= image.GetPixel(xi, yi + 1);
wbb
+= (ushort)(wc * clr.B); wgg += (ushort)(wc * clr.G); wrr += (ushort)(wc * clr.R);

clr
= image.GetPixel(xi + 1, yi + 1);
wbb
+= (ushort)(wd * clr.B); wgg += (ushort)(wd * clr.G); wrr += (ushort)(wd * clr.R);

return Color.FromArgb(255, wrr >> 8, wgg >> 8, wbb >> 8);
}
else
{
float t1 = x - xi, t2 = y - yi;
float d = t1 * t2;
float b = t1 - d;
float c = t2 - d;
float a = 1 - t1 - c;

Color rgb11, rgb21, rgb12, rgb22;
rgb11
= GetPixelColorWithOverflow(ref image, xi, yi);
rgb21
= GetPixelColorWithOverflow(ref image, xi + 1, yi);
rgb12
= GetPixelColorWithOverflow(ref image, xi, yi + 1);
rgb22
= GetPixelColorWithOverflow(ref image, xi + 1, yi + 1);

//calculate linear interpolation
return Color.FromArgb(255,
(
byte)(a * rgb11.R + b * rgb21.R + c * rgb12.R + d * rgb22.R),
(
byte)(a * rgb11.G + b * rgb21.G + c * rgb12.G + d * rgb22.G),
(
byte)(a * rgb11.B + b * rgb21.B + c * rgb12.B + d * rgb22.B));
}
}

static Color GetPixelColorWithOverflow(ref Bitmap image, long x, long y)
{
if (!IsInside(ref image, x, y))
{
return Color.FromArgb(255, 255, 255, 255);
}

return image.GetPixel((int)x, (int)y);
}

static bool IsInside(ref Bitmap image, long x, long y)
{
return (0 <= y && y < image.Height && 0 <= x && x < image.Width);
}

private void transformEllipseToolStripMenuItem_Click(object sender, EventArgs e)
{
Bitmap image
= new Bitmap("D:\\PSD\\info1.jpg");

int x, y;
float x1, y1;
float fx, fy, xmid, ymid, ar;
Bitmap image2
= new Bitmap(image);

xmid
= (float)(image.Width / 2.0);
ymid
= (float)(image.Height / 2.0);
ar
= (float)(image.Height) / (float)(image.Width);
for (y = 0; y < image.Height; y++)
{
for (x = 0; x < image.Width; x++)
{
ComputePixel(ar
* (x - xmid), y - ymid, out fx, out fy);
x1
= xmid + fx / ar;
y1
= ymid + fy;

image2.SetPixel(x, y, GetPixelColorInterpolated(
ref image, x1, y1));
}
}

this.pictureBox1.Image = image2;
}

 

 

 

 

收获园豆:10
Launcher | 高人七级 |园豆:45050 | 2010-08-27 17:26
不会吧!你这哪儿是缩放啊!你这是图像扭曲!
Launcher | 园豆:45050 (高人七级) | 2010-08-27 17:47
是这个样子吗? http://www.topboy.cn/?p=10
Launcher | 园豆:45050 (高人七级) | 2010-08-27 17:50
我想要的是一个正方形图像,把四个边都向外凸起(形成一个圆),图像填充整个圆形。
.zZ | 园豆:225 (菜鸟二级) | 2010-08-27 22:56
@.zZ:我知道你的意思,比较复杂啊!要不你也先看看这个: http://www.codeproject.com/KB/graphics/cximage.aspx http://sourceforge.net/projects/opencvlibrary/ 看里面有没有你要的算法。
Launcher | 园豆:45050 (高人七级) | 2010-08-27 23:07
@.zZ:我还在看Photo Shop ,看看哪个功能是图像扭曲的,找到功能名称了,才能找算法,这样的算法应该有好多种,变出来的效果也不同。
Launcher | 园豆:45050 (高人七级) | 2010-08-27 23:08
@.zZ:我在这个软件中找到了 http://www.codeproject.com/KB/graphics/cximage.aspx CxImage>>Demo>>Ellipse Transform能实现你的效果。 我贴了个图。
Launcher | 园豆:45050 (高人七级) | 2010-08-27 23:13
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册