简介

当前C#剪切图片的案例挺多的,但是用C++的还比较少。但目前的项目需要剪切图片,我也知道用OpenCV比较简单,但是自己又不想在项目中配置一大堆OpenCV的东西,因为项目不怎么需要哪个。

本篇博文包含了三个知识点:图片剪切,字节数组和IStream的转换,Stream和Image类的转换。

图片剪切

首先自己搜了网上C++的剪切图片的方法,然后发现GDI+ 中的DrawImage这个函数可以剪切图片。

Status DrawImage(IN Image* image,
                     IN const RectF& destRect,
                     IN REAL srcx,
                     IN REAL srcy,
                     IN REAL srcwidth,
                     IN REAL srcheight,
                     IN Unit srcUnit,
                     IN const ImageAttributes* imageAttributes = NULL,
                     IN DrawImageAbort callback = NULL,
                     IN VOID* callbackData = NULL)

字节数组和IStream的转换

1、在全局区创建一块内存句柄,用于目标流;
    HGLOBAL hDesMem = GlobalAlloc(GMEM_MOVEABLE, ImageSize);
    IStream *pDesStream = NULL;
    CreateStreamOnHGlobal(hDesMem, TRUE, &pDesStream);
    BYTE *pDesData = (BYTE *)GlobalLock(hDesMem);
2、.复制内存,到申请的全局空间中。
    CopyMemory(pDesData, imgSrc, ImageSize);
    GlobalUnlock(hDesMem);

3、最后要记得释放全局空间,释放流。

GlobalFree(hDesMem);    // 释放全局空间
    pDesStream->Release();
    pOutStream->Release();

IStream和Image类的转换

在我花了两个小时查看Image类之后,发现里面有一个Image的构造函数,可以通过IStream的方式来创建实例。

Image(
        IN IStream* stream,
        IN BOOL useEmbeddedColorManagement = FALSE
    );

后来发现FromStream的函数也可以转为Image指针:

inline Image*  Image::FromStream(
    IN IStream* stream,
    IN BOOL useEmbeddedColorManagement
    )

include <gdiplus.h>#pragma comment(lib, "gdiplus.lib")using namespace Gdiplus;// 功能:切割图像,或缩放图像
// 参数:imgSrc,源图片字节数组,
//       ImageSize:原图片的大小
//       imgDst:目标图片的缓冲区地址
//       xPos:目标图片左上角x坐标
//       yPos:目标图片左上角y坐标
//       Width:目标图片宽度
//       Height:目标图片高度
// 返回值:失败返回0,否则返回目标图片的大小
DWORD CutPicture(BYTE *imgSrc, int ImageSize, BYTE* imgDst, int xPos, int yPos, int Width, int Height)
{int nRet = -1;if (Width<=0 || Height <=0 || imgSrc==nullptr || ImageSize<=0){return 0;}GdiplusStartupInput gdiplusstartupinput;ULONG_PTR gdiplustoken;DWORD nDstSize = 0;GdiplusStartup(&gdiplustoken, &gdiplusstartupinput, NULL);{CLSID clsid;nRet = GetCodecClsid(L"image/jpeg", &clsid);if (nRet == -1){GdiplusShutdown(gdiplustoken);return 0;}//再创建一块内存句柄,用于目标流HGLOBAL hDesMem = GlobalAlloc(GMEM_MOVEABLE, ImageSize);IStream *pDesStream = NULL;CreateStreamOnHGlobal(hDesMem, TRUE, &pDesStream);BYTE *pDesData = (BYTE *)GlobalLock(hDesMem);//3.复制内存,到申请的全局空间中。CopyMemory(pDesData, imgSrc, ImageSize);GlobalUnlock(hDesMem);// 4. 重建ImageImage *bmSrc = Image::FromStream(pDesStream);//        bmSrc->Save(L"E:\\test3.jpg", &clsid, NULL);int w = 0, h = 0;w = bmSrc->GetWidth();h = bmSrc->GetHeight();if (w < h) //图片是竖着的 交换Width和Height{int nTemp = Width;Width = Height;Height = nTemp;}Bitmap *bmPhoto = new Bitmap(Width, Height);  // elvsi待解决bmPhoto->SetResolution(bmSrc->GetHorizontalResolution(), bmSrc->GetVerticalResolution());//bmPhoto->SetResolution(Width, Height);Graphics grPhoto(bmPhoto);grPhoto.Clear((ARGB)Color::White);grPhoto.SetInterpolationMode(InterpolationModeHighQualityBicubic);Rect dest(0, 0, w, h);grPhoto.DrawImage((Image*)bmSrc, dest, xPos, yPos, Width, Height, UnitPixel);//     bmPhoto->Save(L"E:\\test4.jpg", &clsid, NULL);//2.创建流IStream *pOutStream = NULL;ULARGE_INTEGER   pSeek;LARGE_INTEGER    dlibMove = { 0 };CreateStreamOnHGlobal(NULL, TRUE, &pOutStream);//以JPEG图片格式储存数据到流中bmPhoto->Save(pOutStream, &clsid, NULL);pOutStream->Seek(dlibMove, STREAM_SEEK_SET, &pSeek);pOutStream->Read(imgDst, ImageSize, &nDstSize);GlobalFree(hDesMem);   // 释放全局空间delete bmSrc;delete bmPhoto;pDesStream->Release();pOutStream->Release();}GdiplusShutdown(gdiplustoken);return nDstSize;
}

总结

第一次发博文,如果有说的不对的地方,还望各位大牛包容和指正。

C++ 使用GDI+剪切图片相关推荐

  1. 使用GDI+缩放图片文件

    总结一下个人所知道的使用GDI+缩放图片的方法. 方法一:最简单的,使用GetThumbnailImage,这个方法的局限性对支持内嵌缩略图的图片文件无效. 因为MSDN中提到:如果图片文件有内嵌的缩 ...

  2. 关于解决 从相册中选择照片后无法剪切图片以及无法加载图片的问题

    程序分析: 主要分两个部分 (1)先拍照,然后剪切,最后显示出来.    (2)从相册中选择一张照片进行剪切然后显示出来 代码参照<第一行代码>,书中的代码运行时(2)出现了问题,无法剪切 ...

  3. python批量裁剪图片_python通过opencv实现批量剪切图片

    上一篇文章中,我们介绍了python实现图片处理和特征提取详解,这里我们再来看看Python通过OpenCV实现批量剪切图片,具体如下. 做图像处理需要大批量的修改图片尺寸来做训练样本,为此本程序借助 ...

  4. python批量裁剪图片_python批量剪切图片实现代码

    例子,python入门实例,python实现图片批量剪切. 代码: 代码示例: #!/usr/bin/python # www.# import os from PIL import Image #批 ...

  5. HTML5之canvas剪切图片

    有时UI设计效果图,设定图片某个角不可见,但上传的图片又不全是PNG透明图,那么Canvas就能帮忙解决困扰啦,自己根据需求做的一个实例,实现这样的效果,以下贴代码 <!doctype html ...

  6. 剪切图片的某个部分(2)

    前言 上一篇博客--剪切图片的某个部分,发现一个巨大的问题

  7. Java剪切图片为圆形,并使边缘透明。

    剪切图片为圆形,并使边缘透明. 将图片剪切为圆形并使边缘透明 效果图: 看起来朦胧的 但是放进面板之后色彩与原图一致 public static void k() {BufferedImage bi1 ...

  8. vue-cropper剪切图片保存

    1.npm install vue-cropper -S 2.按照完直接使用即可,注意下配置: <template><div class="ivu-upload" ...

  9. java 剪切图片点坐标_详细介绍java根据坐标截取图片的实例代码

    这篇文章主要介绍了java 根据坐标截取图片实例代码的相关资料,需要的朋友可以参考下 java 根据坐标截取图片 实例代码:代码中有不是注释,很好看懂!package com.json.test; i ...

  10. 一种使用GDI+对图片尺寸和质量的压缩方法

    今天同事向我询问图片压缩的算法,我想起大概两三年前做过的一个项目.其中包含了尺寸和质量两种压缩算法,并且支持JPEG.bmp.PNG等格式.今天把这段逻辑贴出来,供大家参考.(转载请指明来源于brea ...

最新文章

  1. ADMT3.2域迁移之Server2003至Server2012系列(八)生成密钥文件及安装密码迁移工具...
  2. 红外感应自动出水水龙头的电路原理
  3. Android TimePicker 不能响应直接输入的问题
  4. Flask框架(flask中的request对象,获取请求参数,保存上传的文件)
  5. php mysql 值是否存在_php检测mysql表是否存在的方法小结
  6. java和opencv配置_Java——OpenCVWindows配置和项目中jar包的简单配置
  7. 学成在线--14.使用RabbitMQ完成页面发布
  8. OpenCV与图像处理学习十六——模板匹配
  9. sql递归查询上级_递归的实际业务场景之MySQL 递归查询
  10. AI 用神经网络实现序列到序列的学习
  11. #怎样获取当前时间和时区_JDK1.8新增日期时间类型
  12. 内网端口映射工具之80端口映射和全端口映射及辅助发布网站应用
  13. 联想 计算机无线网络设置方法,联想笔记本无线网络开关,教您联想笔记本无线网络开关...
  14. PHP编写poc,代码实战/萌新如何编写sql注入的poc
  15. 【Android】Android Studio Profiler Memery (一)
  16. mysql router docker_MySQL Route负载均衡与读写分离Docker环境使用
  17. 计算机基础西南大学,西南大学计算机基础.docx
  18. 大学python挂科补考_大学挂科后补考不过怎么样一种体验?
  19. 落魄前端,整理给自己的前端知识体系复习大纲(上篇,2w字)
  20. chrome 安装插件(无需翻墙)

热门文章

  1. 平面设计中的对比设计技巧
  2. 计算机教育课题申请报告,课题结项申请报告
  3. CDR是什么?CorelDRAW矢量绘图
  4. 实战 | 电感元件定位--Halcon与OpenCV实现详解(附源码)
  5. 鹏业安装算量软件运行环境_安装算量软件电脑配置
  6. 自己做一个小项目python_【Python】第一个微信小项目
  7. 【转】HDMI视频分配器的功能及原理
  8. Bootstrap框架使用及可视化布局
  9. 用 Boost.extension 做C/C++插件
  10. oracle访问emp表,通过deptno查询Emp表中雇员信息(oracle)