如题
我现在用的是bitmap.GetPixel和bitmap.SetPixel,请问有没有办法用ColorMatrix来做或其他的一些高效的方法?另画透明位图:我现在有2幅图,一副是要显示的图片A,另一副是遮照(mask)B,只有黑白2色,2幅图片大小一样,要实现的方法就是让A只显示B的白色部分的区域,小弟愚钝,现在也是用GetPixel和SetPixel来做的。
请教各位大虾,高效的处理方法,Gdi+里能不能有gid中那样的光栅操作来运算图片阿?
我现在用的是bitmap.GetPixel和bitmap.SetPixel,请问有没有办法用ColorMatrix来做或其他的一些高效的方法?另画透明位图:我现在有2幅图,一副是要显示的图片A,另一副是遮照(mask)B,只有黑白2色,2幅图片大小一样,要实现的方法就是让A只显示B的白色部分的区域,小弟愚钝,现在也是用GetPixel和SetPixel来做的。
请教各位大虾,高效的处理方法,Gdi+里能不能有gid中那样的光栅操作来运算图片阿?
解决方案 »
- TopGrid 3.01 安装错误
- 高手请进...在线急等!!!!rmgridreport 预览报错
- 做好的程序在不同的电脑是运行出现问题,大家帮我看一下,急!!!
- 求助:关于INI写二进制流
- 数据库备份与恢复的问题
- 关于doa控件使用的一个很菜的问题?
- 哪位大哥知道,怎么在Delphi 下动态创建表?
- 如何取得DataSet过滤后的记录数?
- 紧急求救,有谁用delphi 开发过 snmp 代理啊?
- TeeChart 监视CPU温度,可以从右向左出现填满后开始移动,横座标显示几分钟前吗?
- Delphi程序重新启动和开机启动问题~~~
- 使用ServerSocket,close_wait什么时候出现?怎样避免出现close_wait?
/// 图像明暗调整
/// </summary>
/// <param name="b">原始位图</param>
/// <param name="degree">亮度[-255, 255]</param>
/// <returns></returns>
public static Bitmap Ki1381Lighten(Bitmap b, int degree)
{
if (b == null)
{
return null;
} if (degree < -255) degree = -255;
if (degree > 255) degree = 255; try
{ int width = b.Width;
int height = b.Height; int pix = 0; BitmapData data = b.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); unsafe
{
byte* p = (byte*)data.Scan0;
int offset = data.Stride - width * 3;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
// 处理指定位置像素的亮度
for (int i = 0; i < 3; i++)
{
pix = p[i] + degree; if (degree < 0) p[i] = (byte)Math.Max(0, pix);
if (degree > 0) p[i] = (byte)Math.Min(255, pix); } // i
p += 3;
} // x
p += offset;
} // y
} b.UnlockBits(data); return b;
}
catch
{
return null;
} } // end of Lighten编译时要启用“允许不安全代码”
// ****************************************************************************
// 亮度校正
// 参数:
// bmp 输入Bitmap
// bmpOut 输出Bitmap
// s 校正值
// ****************************************************************************
function KiBright(bmp:TBitmap;var bmpOut:TBitmap;s:integer):boolean;
var
p: PByteArray;
x, y: Integer;
begin
try
//24位真彩色
Bmp.PixelFormat := pf24Bit;
bmpOut.PixelFormat := pf24Bit; bmpOut.Width := bmp.Width;
bmpOut.Height := bmp.Height; for y := 0 to Bmp.Height - 1 do
begin
p := Bmp.scanline[y];
for x := 0 to Bmp.Width - 1 do
begin
//每个象素点的R、G、B分量进行调节
begin
if s>0 then
begin
p[x * 3] := Min(255, p[x * 3] + s); //不能越界,限制在0~255
p[x * 3 + 1] := Min(255, p[x * 3 + 1] + s);
p[x * 3 + 2] := Min(255, p[x * 3 + 2] + s);
end
else begin
p[x * 3] := max(0, p[x * 3] + s); //不能越界,限制在 -255~0
p[x * 3 + 1] := max(0, p[x * 3 + 1] + s);
p[x * 3 + 2] := max(0, p[x * 3 + 2] + s);
end;
end;
end;
end; bmpOut.Assign(bmp);
Result := true;
except
Result := false;
end;end;
第一个问题你的方法和我类似,就是逐一的判断和设置每一点,我现在用的是Gdi+,我想都是gdi+了,应该有办法效率更高吧,你C#的那个例子也许比我现在的要快,怎么说也是移动指针,但是delphi里我用的是gdiplus的库,不知道怎么找到那个bitmapData,就是图像的数据第2个问题,我现在就是同时读取2幅图,根据遮照图的R值来设置图像的Alpha值,也是逐点扫描,然后设置,效率可想而知,如果用以前的Gdi倒是有快速的光栅操作可以实现。
gdi+中,如果TGPbitmap已经Create了,应该怎么改变width和height的值啊
我现在总是先Free,然后在Create一边,有没有更好de办法啊
/// Gamma校正
/// </summary>
/// <param name="bmp">输入Bitmap</param>
/// <param name="val">[0 <-明- 1 -暗-> 2]</param>
/// <returns>输出Bitmap</returns>
public static Bitmap KiGamma(Bitmap bmp, float val)
{
if (bmp == null)
{
return null;
} // 1表示无变化,就不做
if (val == 1.0000f) return bmp; try
{
Bitmap b = new Bitmap(bmp.Width, bmp.Height);
Graphics g = Graphics.FromImage(b);
ImageAttributes attr = new ImageAttributes(); attr.SetGamma(val, ColorAdjustType.Bitmap);
g.DrawImage(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height), 0, 0, bmp.Width, bmp.Height, GraphicsUnit.Pixel, attr);
g.Dispose();
return b;
}
catch
{
return null;
}
}另外,Bmp.scanline速度也不慢啊,比一个个点傻取快得多
var
attr: TGpImageAttributes;
g: TGpGraphics;
Image: TGpImage;
begin
.....
attr := TGpImageAttributes.Create;
attr.SetColorKey(aclWhite, aclWhite); // 设置白色为透明显示
g.DrawImage(Image, MakeRect(0, 0, Image.GetWidth, Image.GetHeight), 0, 0, Image.GetWidth, Image.GetHeight, UnitPixel, attr);
attr.Free;
...
end;