file-type

基于MFC实现图片上传功能的完整实例与源码解析

RAR文件

5星 · 超过95%的资源 | 下载需积分: 9 | 45KB | 更新于2025-09-12 | 38 浏览量 | 15 下载量 举报 收藏
download 立即下载
在Windows平台开发中,使用MFC(Microsoft Foundation Classes)进行图像上传功能的实现是一个较为典型且具有挑战性的应用场景。本文件“MFC UploadPhoto实例加源码.rar”提供了一个基于MFC框架的图片上传实例,并附带完整的源代码,非常适合开发者学习和参考。以下将从标题、描述、标签及压缩包中的子文件结构出发,深入解析相关的技术知识点。 首先,从标题“MFC UploadPhoto实例加源码.rar”来看,本文件的核心在于“UploadPhoto”,即图片上传功能。开发者通过MFC类库实现了一个可以将本地图片文件上传至服务器的客户端程序。MFC作为微软提供的一套C++类库,封装了Windows API和COM接口,使得开发者可以更便捷地构建Windows应用程序界面与逻辑。在本例中,开发者利用MFC实现了图形界面操作,用户可以选择本地图片并通过HTTP协议将其上传至指定服务器。此外,文件名中提到“实例加源码”,说明该文件不仅包含可执行程序(.exe),还提供了完整的开发源代码,便于学习其内部实现机制。 从描述部分来看,重点在于如何通过HTTP协议实现POST请求来上传数据。在HTTP协议中,POST请求常用于向服务器发送数据,其关键在于请求头中的Content-Type字段。对于普通的表单数据提交,通常会将Content-Type设置为application/x-www-form-urlencoded,此时发送的数据格式为键值对形式,例如:userid=lilu&data=post图片类&name=天漏客。这种格式适用于文本数据的提交,但在上传文件(如图片)时则需要使用另一种格式——multipart/form-data。 multipart/form-data是一种更为复杂的数据编码方式,专门用于支持文件上传。在这种模式下,HTTP请求头中除了设置Content-Type为multipart/form-data之外,还需要定义一个boundary参数,如boundary=xxxxxxx。该boundary值是一个唯一的字符串,用于分隔请求体中的各个数据块。在请求体中,每一块数据都以“--”加上boundary值开始,以“--”加上boundary值加上“--”结束。每个数据块之间通过boundary进行分隔,并且每个数据块都包含自己的头部信息(如Content-Disposition和Content-Type),用于描述该数据块的内容类型和用途。例如,在上传图片时,一个数据块可能用于描述表单字段信息,另一个数据块则用于传输图片的二进制数据。 具体到本实例中,开发者需要手动构造HTTP请求头和请求体。首先设置Content-Type为multipart/form-data,并指定一个唯一的boundary字符串。然后构造请求体内容,包括表单字段和图片数据。表单字段仍然可以使用类似userid=lilu这样的键值对形式,而图片数据则需要读取本地文件的二进制内容,并将其按照multipart/form-data的格式进行拼接。最后,将构造好的HTTP请求通过WinInet或WinHTTP等Windows网络API发送到服务器端。 进一步分析压缩包中的子文件列表,可以更深入理解该实例的代码结构与实现方式: - **StdAfx.cpp / StdAfx.h**:这是MFC项目的预编译头文件。预编译头机制可以加快编译速度,通常在StdAfx.h中包含项目中常用的头文件,如afxwin.h、afxext.h等MFC核心类库头文件。 - **UploadPhoto.cpp / UploadPhotoDlg.cpp**:UploadPhoto.cpp是主程序入口文件,通常包含CWinApp派生类的定义和初始化代码;UploadPhotoDlg.cpp则是主对话框类的实现文件,包含界面控件的事件处理函数和图片上传的核心逻辑代码。 - **UploadPhoto.ncb**:这是Visual Studio的IntelliSense数据库文件,用于提供代码自动完成、语法检查等功能,不参与编译。 - **UploadPhoto.exe**:这是编译后的可执行程序,用户可以直接运行该程序进行图片上传测试。 - **ReadMe.txt**:说明文档,通常包含项目的使用方法、注意事项和版本信息。 - **UploadPhoto.rc / UploadPhoto.aps**:资源文件,其中.rc文件定义了对话框界面、图标、菜单等资源;.aps文件是资源的二进制预编译版本,加快资源加载速度。 - **SendData.h**:这是一个自定义头文件,可能定义了用于发送HTTP请求的函数或类,封装了构造multipart/form-data请求体的逻辑,包括拼接boundary、设置Content-Type、读取文件数据等。 综上所述,该MFC UploadPhoto实例展示了如何在MFC环境下实现图片上传功能,涵盖HTTP协议的基础知识、multipart/form-data数据格式的构造方法、MFC框架的使用技巧以及Windows网络API的调用方式。通过分析该实例的源码,开发者可以掌握如何在实际项目中处理文件上传问题,并深入理解HTTP协议在客户端与服务器通信中的应用机制。此外,该实例也为进一步扩展功能(如多文件上传、进度条显示、异步上传等)提供了良好的代码基础和架构参考。

相关推荐

filetype

java.lang.Error: Unresolved compilation problems: The method getPart(String) is undefined for the type HttpServletRequest The method setExamineePic(String, String) is undefined for the type BaoMingDB at com.baoming.action.UploadPhoto.doPost(UploadPhoto.java:28) at javax.servlet.http.HttpServlet.service(HttpServlet.java:646) at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:750)这个错误怎么办

filetype

const app = getApp() Page({ data: { canIUse: wx.canIUse('button.open-type.getUserInfo'), src: "", //图片的链接 baidutoken: "", base64: "", msg: "" }, //拍照 takePhoto() { var that = this; //拍照 const ctx = wx.createCameraContext() ctx.takePhoto({ quality: 'high', success: (res) => { this.setData({ src: res.tempImagePath //获取图片 }) //图片base64编码 wx.getFileSystemManager().readFile({ filePath: this.data.src, //选择图片返回的相对路径 encoding: 'base64', //编码格式 success: res => { //成功的回调 this.setData({ base64: res.data }) } }) this.getBaiduToken(); } //拍照成功结束 }) //调用相机结束 //失败尝试 wx.showToast({ title: '请重试', icon: 'loading', duration: 500 }) }, error(e) { console.log(e.detail) }, getBaiduToken() { var that = this; //acess_token获取,qs:需要多次尝试 wx.request({ url: 'https://aip.baidubce.com/oauth/2.0/token', //是真实的接口地址 data: { grant_type: 'client_credentials', client_id: 'xxxxxxxxxxxxxxxxxxx', //用你创建的应用的API Key client_secret: 'xxxxxxxxxxxxxxxxxxx' //用你创建的应用的Secret Key }, header: { 'Content-Type': 'application/json' // 默认值 }, success(res) { that.setData({ baidutoken: res.data.access_token //获取到token }) that.uploadPhoto(); } }) }, uploadPhoto() { var that = this; //上传人脸进行注册-----test wx.request({ url: 'https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add?access_token=' + this.data.baidutoken, method: 'POST', data: { image: this.data.base64, image_type: 'BASE64', group_id: 'xh_0713', //自己建的用户组id user_id: 'xiehao' //这里获取用户昵称 }, header: { 'Content-Type': 'application/json' // 默认值 }, success(res) { that.setData({ msg: res.d

filetype

@PostMapping("/uploadPmPhoto") @ApiOperation("拍照上传图片进行识别") @AutoLog(appName = ApiConst.TRACK_IN,moduleName = "uploadPhoto") public R<ImageReturnDto> uploadPmPhoto(HttpServletRequest request) { log.info("上传图片进行识别:" + CurrentUser.getUser().getWorkNo()); ImageReturnDto imageReturnDto = new ImageReturnDto(); MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest)request; MultiValueMap<String, MultipartFile> fileMap = multipartHttpServletRequest.getMultiFileMap(); MultipartFile file = fileMap.getFirst("file"); try { if(ocrUrl2Flag){ String originalFilename = file.getOriginalFilename(); // 生成临时文件 String tempPath = System.getProperty("java.io.tmpdir"); File tempFile = new File(tempPath + originalFilename); InputStream inputStream = null; if (!tempFile.exists()) { inputStream = file.getInputStream(); Files.copy(inputStream, tempFile.toPath()); } FileSystemResource resource = new FileSystemResource(tempFile); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); headers.set("Accept-Charset", "UTF-8"); MultiValueMap<String,Object> body = new LinkedMultiValueMap<>(); body.add("file",resource); HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(body, headers); ResponseEntity<String> responseEntity = restTemplate.exchange(ocrUrl2, HttpMethod.POST, httpEntity, new ParameterizedTypeReference<String>() { }); Files.delete(tempFile.toPath()); if(responseEntity.getStatusCodeValue() == 200){ JSONObject jsonObject = JSONObject.parseObject(responseEntity.getBody()); imageReturnDto.setOCRText(jsonObject.getString("processedOCRTexts")); imageReturnDto.setImageData(jsonObject.getString("imageData")); log.info("OCR识别结果:{}",jsonObject.getString("processedOCRTexts")); return R.success(imageReturnDto); }else{ log.error("OCR识别服务异常:{}", responseEntity); return R.fail("OCR识别服务异常"); } }else{ String imageOcrDto = multipartHttpServletRequest.getParameter("imageOcrDto"); ImageOcrDto imageOcrDtoNew = new ImageOcrDto(); String base64String = null; byte[] fileBytes = file.getBytes(); base64String = Base64.getEncoder().encodeToString(fileBytes); ImageOcrFileDto imageOcrFileDto = new ImageOcrFileDto(); imageOcrFileDto.setFileName("1.jpg"); imageOcrFileDto.setImageData(base64String); List<ImageOcrFileDto> imageOcrFileDtoList = new ArrayList<>(); imageOcrFileDtoList.add(imageOcrFileDto); imageOcrDtoNew = JSONObject.parseObject(imageOcrDto, ImageOcrDto.class); imageOcrDtoNew.setFiles(imageOcrFileDtoList); ImageOcrDto imageOcr = new ImageOcrDto(); BeanUtils.copyProperties(imageOcrDtoNew,imageOcr); String imageOcrNew = JSONObject.toJSONString(imageOcr); String sendPostJson = HttpRequestUtil.sendPost(ocrUrl,imageOcrNew); log.info("OCR识别结果:{}",sendPostJson); JSONObject jsonObject = JSONObject.parseObject(sendPostJson); JSONArray jsonObjectArray = jsonObject.getJSONArray("1.jpg"); if(!StringUtils.isEmpty(jsonObjectArray)){ StringBuilder stringBuilder = new StringBuilder(); for (int i=0;i<jsonObjectArray.size();i++) { JSONObject recipe = JSONObject.parseObject(jsonObjectArray.get(i).toString()); ImageOcrVO imageOcrVO = JSONObject.parseObject(String.valueOf(recipe), ImageOcrVO.class); if(org.apache.commons.lang.StringUtils.isNotBlank(imageOcrVO.getOCRText())){ stringBuilder.append(imageOcrVO.getOCRText()); } } imageReturnDto.setOCRText(stringBuilder.toString()); imageReturnDto.setImageData(base64String); return R.success(imageReturnDto); } else { R.fail("图片解析失败"); } } } catch (Exception e){ ErrorLogUtils.saveError(e); log.error("图片识别异常:{}",e.toString()); } return R.success(imageReturnDto); } 如何用postman测试如上方法

weili20000
  • 粉丝: 0
上传资源 快速赚钱