mirror of
https://gitee.com/csharpui/CPF.git
synced 2025-04-05 17:37:51 +08:00
169 lines
5.8 KiB
C#
169 lines
5.8 KiB
C#
//#if Net4
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using CPF.Drawing;
|
|
|
|
namespace CPF.GDIPlus
|
|
{
|
|
public class GDIPlusBitmapLock : IBitmapLockImpl
|
|
{
|
|
System.Drawing.Bitmap bmp;
|
|
System.Drawing.Imaging.BitmapData data;
|
|
int Stride;
|
|
public GDIPlusBitmapLock(GDIPlusBitmap bmp)
|
|
{
|
|
this.bmp = bmp.Bitmap;
|
|
data = this.bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
|
|
Stride = data.Stride;
|
|
}
|
|
|
|
public IntPtr DataPointer
|
|
{
|
|
get
|
|
{
|
|
return data.Scan0;
|
|
}
|
|
}
|
|
|
|
public PixelFormat PixelFormat => PixelFormat.PBgra;
|
|
|
|
public AlphaType AlphaType => AlphaType.Premul;
|
|
|
|
public void Dispose()
|
|
{
|
|
bmp.UnlockBits(data);
|
|
}
|
|
|
|
public unsafe void GetAlpha(in int x, in int y, out byte a)
|
|
{
|
|
byte* numPtr = (byte*)(((data.Scan0) + (y * Stride)) + (x * 4));
|
|
a = numPtr[3];
|
|
}
|
|
|
|
public unsafe void GetPixel(in int x, in int y, out byte a, out byte r, out byte g, out byte b)
|
|
{
|
|
byte* numPtr = (byte*)(((data.Scan0) + (y * Stride)) + (x * 4));
|
|
a = numPtr[3];
|
|
r = numPtr[2];
|
|
g = numPtr[1];
|
|
b = numPtr[0];
|
|
|
|
if (a > 0 && a < 255)
|
|
{
|
|
r = (byte)(r * 255 / a);
|
|
g = (byte)(g * 255 / a);
|
|
b = (byte)(b * 255 / a);
|
|
}
|
|
}
|
|
|
|
public unsafe void SetAlpha(in int x, in int y, in byte a)
|
|
{
|
|
byte* numPtr = (byte*)(((data.Scan0) + (y * Stride)) + (x * 4));
|
|
var oa = numPtr[3];
|
|
numPtr[3] = a;
|
|
if (oa == 0)
|
|
{
|
|
return;
|
|
}
|
|
numPtr[0] = (byte)(numPtr[0] * a / oa);
|
|
numPtr[1] = (byte)(numPtr[1] * a / oa);
|
|
numPtr[2] = (byte)(numPtr[2] * a / oa);
|
|
}
|
|
|
|
public unsafe void SetPixel(in int x, in int y, in byte a, in byte r, in byte g, in byte b)
|
|
{
|
|
byte* numPtr = (byte*)(((data.Scan0) + (y * Stride)) + (x * 4));
|
|
|
|
numPtr[0] = (byte)(b * a / 255);
|
|
numPtr[1] = (byte)(g * a / 255);
|
|
numPtr[2] = (byte)(r * a / 255);
|
|
numPtr[3] = a;
|
|
}
|
|
|
|
public unsafe void WritePixels(PixelRect rect, byte* sourceBuffer, PixelFormat sourcePixelFormat)
|
|
{
|
|
int offset = (bmp.Width - rect.Width) * 4;
|
|
var p = sourceBuffer + rect.Y * bmp.Width * 4 + rect.X * 4;
|
|
var target = (byte*)data.Scan0 + rect.Y * bmp.Width * 4 + rect.X * 4;
|
|
var rh = rect.Height;
|
|
var rw = rect.Width;
|
|
switch (sourcePixelFormat)
|
|
{
|
|
case PixelFormat.Undefined:
|
|
break;
|
|
case PixelFormat.PRgba:
|
|
for (int y = 0; y < rh; y++)
|
|
{
|
|
for (int x = 0; x < rw; x++)
|
|
{
|
|
//SetPixel(x + dirtyRect.X, y + dirtyRect.Y, p[3], p[2], p[1], p[0]);
|
|
target[0] = p[2];
|
|
target[1] = p[1];
|
|
target[2] = p[0];
|
|
target[3] = p[3];
|
|
target += 4;
|
|
p += 4;
|
|
} // x
|
|
p += offset;
|
|
target += offset;
|
|
} // y
|
|
break;
|
|
case PixelFormat.Rgba:
|
|
for (int y = 0; y < rh; y++)
|
|
{
|
|
for (int x = 0; x < rw; x++)
|
|
{
|
|
var a = p[3];
|
|
target[0] = (byte)(p[2] * a / 255);
|
|
target[1] = (byte)(p[1] * a / 255);
|
|
target[2] = (byte)(p[0] * a / 255);
|
|
target[3] = a;
|
|
target += 4;
|
|
p += 4;
|
|
} // x
|
|
p += offset;
|
|
target += offset;
|
|
} // y
|
|
break;
|
|
case PixelFormat.PBgra:
|
|
for (int y = 0; y < rh; y++)
|
|
{
|
|
for (int x = 0; x < rw; x++)
|
|
{
|
|
//SetPixel(x + dirtyRect.X, y + dirtyRect.Y, p[3], p[2], p[1], p[0]);
|
|
target[0] = p[0];
|
|
target[1] = p[1];
|
|
target[2] = p[2];
|
|
target[3] = p[3];
|
|
target += 4;
|
|
p += 4;
|
|
} // x
|
|
p += offset;
|
|
target += offset;
|
|
} // y
|
|
break;
|
|
case PixelFormat.Bgra:
|
|
for (int y = 0; y < rh; y++)
|
|
{
|
|
for (int x = 0; x < rw; x++)
|
|
{
|
|
var a = p[3];
|
|
target[0] = (byte)(p[0] * a / 255);
|
|
target[1] = (byte)(p[1] * a / 255);
|
|
target[2] = (byte)(p[2] * a / 255);
|
|
target[3] = a;
|
|
target += 4;
|
|
p += 4;
|
|
} // x
|
|
p += offset;
|
|
target += offset;
|
|
} // y
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//#endif |