天涯 = tianyaclub.net
天涯 是一个全球华人分享和交流的地方
现在注册
已注册用户请  登录
😊天涯最新网址→ tianya666.com tianya666.net 点击查看说明 天涯秘籍
手机浏览器访问网址,自适应移动端屏幕查看
😊你好呀朋友→了解天涯 帮助文档 使用指南
天涯发帖消耗社区币,每日登录免费领取
知之为知之,不知为不知,是知也。
😊好好说话→ 在一个公共空间的公共讨论中,我们应该关注的,是自己能够在这些讨论中提供什么样的建设性增益,而不是那些纯粹个人的感受。好好说话,不要把戾气宣泄于他人。
坐看云起2024 · 2024年5月13日 18:53 · 623 次点击
这是一个创建于 873 天前的主题,其中的信息可能已经发生改变。

有网页需要我的学习源代码,现发在这里
///
/// 图像帮助类
///
class Image : IDisposable
{
// 指向非托管内存的图像数据指针
IntPtr _imageData;
// 图片大小
int _width, _height;
// 图像跨幅(行的大小)
int _stride;
// 图像像素格式
PixelFormat _pixelFormat;
// 是否应该释放图像标志
bool _mustBeDisposed = false;

///
/// 获取指向非托管内存的图像数据指针
///
public IntPtr ImageData => _imageData;

///
/// 获取图像的像素宽度
///
public int Width => _width;

///
/// 获取图像的像素高度
///
public int Height => _height;

///
/// 获取图像的跨幅(行的大小,字节值)
///
public int Stride => _stride;

///
/// 获取图像的像素格式
///
public PixelFormat PixelFormat => _pixelFormat;

///
/// 初始化一个ImageHelper类的新实例
///
/// 锁定的位图数据。
/// 与 FromManagedImage 方法不同,此构造函数不会复制托管映像。这意味着托管映像在使用未映射映像实例时必须保持锁定状态。
private Image(BitmapData bitmapData)
{
this._imageData = bitmapData.Scan0;
this._width = bitmapData.Width;
this._height = bitmapData.Height;
this._stride = bitmapData.Stride;
this._pixelFormat = bitmapData.PixelFormat;
}

///
/// 初始化一个ImageHelper类的新实例
///
/// 指向非托管内存的图像数据指针。
/// Image 的像素宽度.
/// Image 的像素高度.
/// Image 的跨幅.
/// Image 的像素格式
/// 使用此构造函数,请确保所有指定的图像属性都正确且对应于非托管内存缓冲区。如果某些属性指定不正确,则可能导致使用非托管内存时出现异常。
private Image(IntPtr imageData, int width, int height, int stride, PixelFormat pixelFormat)
{
this._imageData = imageData;
this._width = width;
this._height = height;
this._stride = stride;
this._pixelFormat = pixelFormat;
}

///
/// 释放此对象的非托管和托管资源
///
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

///
/// 释放此对象的非托管和托管资源
///
/// 如果为 true,则释放托管资源。
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// 重写方法中,这里释放托管资源
}
// 可用映像内存(如果映像是使用此类分配的)
if (_mustBeDisposed && (_imageData != IntPtr.Zero))
{
Marshal.FreeHGlobal(_imageData);
GC.RemoveMemoryPressure(_stride * _height);
_imageData = IntPtr.Zero;
}
}

///
/// 得到此对象的副本
///
public Image Clone()
{
// 为图像分配内存
IntPtr newImageData = Marshal.AllocHGlobal(_stride * _height);
GC.AddMemoryPressure(_stride * _height);

var rst = new Image(newImageData, _width, _height, _stride, _pixelFormat);
rst._mustBeDisposed = true;

SystemTools.CopyUnmanagedMemory(newImageData, _imageData, _stride * _height);

return rst;
}

2024年5月13日 18:53
需要 后方可回复,如果您还没有账号请
7 条回复  •  2024年6月8日 21:52
  1. 坐看云起2024坐看云起2024
    OP
    2024年5月13日 18:56
    1

    ///
    /// 复制此对象到参数目标对象中
    ///
    /// 要将此图像复制到的目标图像。
    /// 该方法将当前非托管映像复制到指定的映像。目标图像的大小和像素格式必须完全相同。
    public void Copy(Image dest)
    {
    if ((_width != dest._width) || (_height != dest._height) || (_pixelFormat != dest._pixelFormat))
    {
    throw new Exception("目标图像具有与此对象不同的大小或像素格式。");
    }

    if (_stride == dest._stride)
    {
    // 复制图像
    SystemTools.CopyUnmanagedMemory(dest._imageData, _imageData, _stride * _height);
    }
    else
    {
    unsafe
    {
    int dstStride = dest._stride;
    int copyLength = (_stride < dstStride) ? _stride : dstStride;

    byte* src = (byte*)_imageData.ToPointer();
    byte* dst = (byte*)dest._imageData.ToPointer();

    // 复制行
    for (int i = 0; i < _height; i++)
    {
    SystemTools.CopyUnmanagedMemory(dst, src, copyLength);

    dst += dstStride;
    src += _stride;
    }
    }
    }
    }

    ///
    /// 在非托管内存中分配新图片。
    ///
    /// 图像宽度
    /// 图像高度
    /// 图像像素格式.
    /// 在非托管内存中分配具有指定宽高的新图片
    public static Image Create(int width, int height, PixelFormat pixelFormat)
    {
    int bytesPerPixel = 0;
    // 计算每像素的字节数
    switch (pixelFormat)
    {
    case PixelFormat.Format8bppIndexed:
    bytesPerPixel = 1;
    break;
    case PixelFormat.Format16bppGrayScale:
    bytesPerPixel = 2;
    break;
    case PixelFormat.Format24bppRgb:
    bytesPerPixel = 3;
    break;
    case PixelFormat.Format32bppRgb:
    case PixelFormat.Format32bppArgb:
    case PixelFormat.Format32bppPArgb:
    bytesPerPixel = 4;
    break;
    case PixelFormat.Format48bppRgb:
    bytesPerPixel = 6;
    break;
    case PixelFormat.Format64bppArgb:
    case PixelFormat.Format64bppPArgb:
    bytesPerPixel = 8;
    break;
    default:
    throw new Exception("只读的像素格式无效");
    }

    // 检查图像大小
    if ((width <= 0) || (height <= 0))
    {
    throw new Exception("指定的图像大小无效。");
    }

    // 计算跨辐
    int stride = width * bytesPerPixel;
    if (stride % 4 != 0)
    {
    stride += (4 - (stride % 4));
    }

    // 为图片分配内存
    IntPtr imageData = Marshal.AllocHGlobal(stride * height);
    SystemTools.SetUnmanagedMemory(imageData, 0, stride * height);
    GC.AddMemoryPressure(stride * height);

    var image = new Image(imageData, width, height, stride, pixelFormat);
    image._mustBeDisposed = true;

    return image;
    }

    ///
    /// 从指定的托管图像创建非托管映像。
    ///
    /// 源托管图像
    /// 返回新的非托管映像,该映像是源托管映像的副本。
    /// 该方法创建指定托管映像的精确副本,已在非托管内存中分配。
    public static Image FromImage(Bitmap image)
    {
    Image dst = null;

    BitmapData sData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height),
    ImageLockMode.ReadOnly, image.PixelFormat);

    try
    {
    dst = FromImage(sData);
    }
    finally
    {
    image.UnlockBits(sData);
    }

    return dst;
    }

  2. 坐看云起2024坐看云起2024
    OP
    2024年5月13日 18:58
    2

    天涯不支持发布代码,代码都变啦。不发了。

  3. 坐看云起2024坐看云起2024
    OP
    2024年5月28日 00:58
    3

    我的学习笔记视频地址:
    https://www.douyin.com/user/self?modal_id=7372396715510467859&showTab=post
    记得有时间去指导哈。

  4. 坐看云起2024坐看云起2024
    OP
    2024年5月28日 12:29
    4

    我的学习视频地址:
    https://www.douyin.com/user/self?modal_id=7368431640848108812&showTab=post
    有时间了记得去指导哈。

  5. 坐看云起2024坐看云起2024
    OP
    2024年5月28日 12:32
    5

    写出成将图像处理成好看的仙境效果啦。第一张是原图片,第二张是处理后的仙境图片。

  6. 坐看云起2024坐看云起2024
    OP
    2024年5月28日 12:32
    6

    仙境图片:

  7. User1314User1314
    2024年6月8日 21:52
    7

    应该是“网友”吧

添加新回复
5000
如果您要教别人做事,请确认那件事情是您自己确实已经做过并且做得很好的
← tianyaclub.net