VC++把图像内容保存在数据库的例子-程序员宅基地

VC++把图像内容保存在数据库的例子

http://www.codefans.net/articles/1911.shtml


 

VC++结合Access,把图片数据保存在Access数据库中,插入图像数据保存在数据库的相关字段中,这样移植软件比较方便,不过会使数据库迅速变大,可根据你的软件需求选择使用,下面是代码:

 

 

#include "stdafx.h"

#include "InsertImage.h"

#include "InsertImageDlg.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

class CAboutDlg : public CDialog

{

public:

       CAboutDlg();

       enum{ IDD = IDD_ABOUTBOX };

       protected:

       virtualvoid DoDataExchange(CDataExchange* pDX);

protected:

       DECLARE_MESSAGE_MAP()

};

CAboutDlg::CAboutDlg() :CDialog(CAboutDlg::IDD)

{

}

voidCAboutDlg::DoDataExchange(CDataExchange* pDX)

{

       CDialog::DoDataExchange(pDX);

}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)

END_MESSAGE_MAP()

CInsertImageDlg::CInsertImageDlg(CWnd*pParent /*=NULL*/)

       :CDialog(CInsertImageDlg::IDD, pParent)

{

       m_hIcon= AfxGetApp()->LoadIcon(IDR_MAINFRAME);

}

voidCInsertImageDlg::DoDataExchange(CDataExchange* pDX)

{

       CDialog::DoDataExchange(pDX);

       DDX_Control(pDX,IDC_IMAGE, m_Image);

       DDX_Control(pDX,IDC_EDIT1, m_Path);

       DDX_Control(pDX,IDC_COMBO1, m_Combo);

       //}}AFX_DATA_MAP

}

BEGIN_MESSAGE_MAP(CInsertImageDlg, CDialog)

       ON_WM_SYSCOMMAND()

       ON_WM_PAINT()

       ON_WM_QUERYDRAGICON()

       ON_BN_CLICKED(IDC_BUTSELECT,OnButselect)

       ON_BN_CLICKED(IDC_BUTINSERT,OnButinsert)

       ON_WM_CLOSE()

       ON_CBN_SELCHANGE(IDC_COMBO1,OnSelchangeCombo1)

END_MESSAGE_MAP()

BOOL CInsertImageDlg::OnInitDialog()

{

       CDialog::OnInitDialog();

       ASSERT((IDM_ABOUTBOX& 0xFFF0) == IDM_ABOUTBOX);

       ASSERT(IDM_ABOUTBOX< 0xF000);

       CMenu*pSysMenu = GetSystemMenu(FALSE);

       if(pSysMenu != NULL)

       {

              CStringstrAboutMenu;

              strAboutMenu.LoadString(IDS_ABOUTBOX);

              if(!strAboutMenu.IsEmpty())

              {

                     pSysMenu->AppendMenu(MF_SEPARATOR);

                     pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX, strAboutMenu);

              }

       }

       SetIcon(m_hIcon,TRUE);   

       SetIcon(m_hIcon,FALSE);

       OnInitADOConn();

       _bstr_tsql;

       sql= "select * from Picture";

       m_pRecordset.CreateInstance(__uuidof(Recordset));

       m_pRecordset->Open(sql,m_pConnection.GetInterfacePtr()

              ,adOpenDynamic,adLockOptimistic,adCmdText);

       inti=0;

       while(m_pRecordset->adoEOF==0)

       {

              m_Combo.InsertString(i,(char*)(_bstr_t)m_pRecordset->GetCollect("图片名称"));

              m_pRecordset->MoveNext();

              i++;

       }

       m_pRecordset->Close();

       returnTRUE;

}

void CInsertImageDlg::OnSysCommand(UINTnID, LPARAM lParam)

{

       if((nID & 0xFFF0) == IDM_ABOUTBOX)

       {

              CAboutDlgdlgAbout;

              dlgAbout.DoModal();

       }

       else

       {

              CDialog::OnSysCommand(nID,lParam);

       }

}

void CInsertImageDlg::OnPaint()

{

       if(IsIconic())

       {

              CPaintDCdc(this);

              SendMessage(WM_ICONERASEBKGND,(WPARAM) dc.GetSafeHdc(), 0);

              intcxIcon = GetSystemMetrics(SM_CXICON);

              intcyIcon = GetSystemMetrics(SM_CYICON);

              CRectrect;

              GetClientRect(&rect);

              intx = (rect.Width() - cxIcon + 1) / 2;

              inty = (rect.Height() - cyIcon + 1) / 2;

              dc.DrawIcon(x,y, m_hIcon);

       }

       else

       {

              CDialog::OnPaint();

       }

}

HCURSOR CInsertImageDlg::OnQueryDragIcon()

{

       return(HCURSOR) m_hIcon;

}

void CInsertImageDlg::OnButselect()

{

       CFileDialogdlg(true,"bmp",NULL,OFN_HIDEREADONLY |

              OFN_OVERWRITEPROMPT,"位图文件(*.bmp)|*.bmp",this);

       if(dlg.DoModal() == IDOK)

       {

              CStringstrText   = dlg.GetPathName();//取得图片的完整路径

              m_Path.SetWindowText(strText);

              m_StrName= dlg.GetFileName();

              HBITMAPm_hBitmap = (HBITMAP)::LoadImage(AfxGetInstanceHandle(),strText,

                     IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_DEFAULTCOLOR|LR_DEFAULTSIZE);

              if(m_hBitmap != NULL)

              {

                     //使用控件显示图片

                     m_Image.SetBitmap(m_hBitmap);

              }

       }

}

void CInsertImageDlg::OnInitADOConn()

{

       try

       {

              m_pConnection.CreateInstance("ADODB.Connection");//创建连接对象实例

              _bstr_tstrConnect="DRIVER={Microsoft Access Driver (*.mdb)};\

                     uid=;pwd=;DBQ=Database.mdb;";

              m_pConnection->Open(strConnect,"","",adModeUnknown);//打开数据库

       }

       catch(_com_error e)//捕捉错误

       {

              AfxMessageBox(e.Description());//弹出错误

       }

}

void CInsertImageDlg::OnButinsert()

{

       try

       {

              CStringPath;

              m_Path.GetWindowText(Path);

              if(Path.IsEmpty())

              {

                     MessageBox("图片路径不能为空.","提示");

                     return;

              }

              char*m_pBuffer;

              //定义文件对象

              CFilefile;

              //以只读方式打开文件

              if(!file.Open(Path,CFile::modeRead))

              {

                     MessageBox("无法打开BMP文件");

                     return;

              }

              //用于保存文件长度

              DWORDm_filelen;

              //读取文件长度

              m_filelen= file.GetLength();

              //根据文件长度分配数组空间

              m_pBuffer= new char[m_filelen + 1];

              //读取BMP文件到m_pBuffer中

              if(file.ReadHuge(m_pBuffer,m_filelen)!=m_filelen)

              {

                     MessageBox("读取BMP文件是出现错误");

                     return;

              }

              file.Close();

              _bstr_tsql;

              sql= "select*from Picture";

              m_pRecordset.CreateInstance(__uuidof(Recordset));

              m_pRecordset->Open(sql,m_pConnection.GetInterfacePtr()

                     ,adOpenDynamic,adLockOptimistic,adCmdText);

              //添加新行

              m_pRecordset->AddNew();

              VARIANTvarblob;

              SAFEARRAY*psa;

              SAFEARRAYBOUNDrgsabound[1];

              rgsabound[0].lLbound= 0;

              rgsabound[0].cElements= m_filelen;

              //创建数组

              psa= SafeArrayCreate(VT_UI1,1,rgsabound);

              //将m_pBuffer中的图像数据写入数组psa

              for(longi=0;i<(long)m_filelen;i++)

              {

                     SafeArrayPutElement(psa,&i,m_pBuffer++);

              }

              varblob.vt= VT_ARRAY|VT_UI1;

              varblob.parray= psa;

              m_pRecordset->GetFields()->GetItem("图片名称")->Value =(_bstr_t)m_StrName;

              m_pRecordset->GetFields()->GetItem("图片路径")->Value =(_bstr_t)Path;

              //调用AppendChunk()函数将图像数据写入Photo字段

              m_pRecordset->GetFields()->GetItem("图片数据")->AppendChunk(varblob);

              //更新数据库

              m_pRecordset->Update();

              m_pRecordset->Close();

       }

       catch(...)

       {

              MessageBox("操作失败");

              return;

       }

       m_Combo.InsertString(m_Combo.GetCount(),m_StrName);

       MessageBox("操作成功.");

}

void CInsertImageDlg::OnClose()

{

       m_pConnection->Close();

       CDialog::OnClose();

}

void CInsertImageDlg::OnSelchangeCombo1()

{

       HBITMAPm_hBitmap;

       CStringname;

       m_Combo.GetLBText(m_Combo.GetCurSel(),name);

       _bstr_tsql;

       sql= "select*from Picture where 图片名称='"+name+"' ";

       m_pRecordset.CreateInstance(__uuidof(Recordset));

       m_pRecordset->Open(sql,m_pConnection.GetInterfacePtr()

              ,adOpenDynamic,adLockOptimistic,adCmdText);

       //读取图像字段的实际大小

       longlDataSize = m_pRecordset->GetFields()->GetItem("图片数据")->ActualSize;

       char*m_pBuffer;  //定义缓冲变量

       if(lDataSize> 0)

       {

              //从图像字段中读取数据到varBLOB中

              _variant_tvarBLOB;

              varBLOB= m_pRecordset->GetFields()->GetItem("图片数据")->GetChunk(lDataSize);

              if(varBLOB.vt== (VT_ARRAY | VT_UI1))

              {

                     if(m_pBuffer= new char[lDataSize+1])      //分配必要的存储空间

                     {

                            char*pBuf = NULL;

                            SafeArrayAccessData(varBLOB.parray,(void**)&pBuf);

                            memcpy(m_pBuffer,pBuf,lDataSize);///复制数据到缓冲区m_pBuffer

                            SafeArrayUnaccessData(varBLOB.parray);

 

                            //将数据转换为HBITMAP格式

                            LPSTRhDIB;

                            LPVOIDlpDIBBits;

                            BITMAPFILEHEADERbmfHeader;  //用于保存BMP文件头信息,包括类型、大小、位移量等

                            DWORDbmfHeaderLen;  //保存文件头的长度

                            bmfHeaderLen= sizeof(bmfHeader);  //读取文件头的长度

                            //将m_pBuffer中文件头复制到bmfHeader中

                            strncpy((LPSTR)&bmfHeader,(LPSTR)m_pBuffer, bmfHeaderLen);

                            if(bmfHeader.bfType != (*(WORD*)"BM"))  //如果文件类型不对,则返回

                            {

                                   MessageBox("BMP文件格式不准确");

                                   return;

                            }

                            hDIB= m_pBuffer + bmfHeaderLen;  //将指针移至文件头后面

                            //读取BMP文件的图像数据,包括坐标及颜色格式等信息到BITMAPINFOHEADER对象

                            BITMAPINFOHEADER&bmiHeader = *(LPBITMAPINFOHEADER)hDIB;

                            //读取BMP文件的图像数据,包括坐标及颜色格式等信息到BITMAPINFO对象

                            BITMAPINFO&bmInfo = *(LPBITMAPINFO)hDIB ;

                            //根据bfOffBits属性将指针移至文件头后

                            lpDIBBits= (m_pBuffer) + ((BITMAPFILEHEADER *)m_pBuffer)->bfOffBits;

                            CClientDCdc(this);  //生成一个与当前窗口相关的CClientDC,用于管理输出设置

                            //生成DIBitmap数据

                            m_hBitmap= CreateDIBitmap(dc.m_hDC,&bmiHeader,CBM_INIT,lpDIBBits,&bmInfo,DIB_RGB_COLORS);

                     }

              }

       }

       m_Image.SetBitmap(m_hBitmap);

}

 

 

 



















版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/chla/article/details/42241875

智能推荐

科研文献定制-直径2.2-3.5nm[Ag58S13(SAd)32] 甲基硅硫银簇;适配体AS1411标记绿色荧光AgNCs在催化领域的应用瑞禧_ag56s13-程序员宅基地

文章浏览阅读148次。金属纳米团簇具有光学、催化、手性、磁性、电化学等性质,其中光学性质:包括光学吸收、光致发光、非线性特性、超快动力学。金属纳米团簇的非线性光学性质包括双光子吸收(TPA),双光子荧光(TPF)和二次/三次谐波产生(SHG / THG)。由于这些性质,金属纳米团簇成用于高分辨多光子成像和光学限制应用领域。催化活性及其催化领域应用催化类型金属纳米团簇的超小尺寸提供了几个不同的特征,包括高比表面积,高比例的低配位原子,量子尺寸效应,可调组成和独特的表面结构(例如,口袋状位点),使纳米团簇成为一类独特的催化_ag56s13

jQuery的常用API_jq api-程序员宅基地

文章浏览阅读380次。jQuery 是一个 JavaScript 库。jQuery 极大地简化了 JavaScript 编程。jquery插件里面提供一个全局的对象$和jQuery对象,本质是一个函数,$(document).ready(function(){ //预加载函数;//method})$(function(){ //预加载语法糖;//method})$("#p1") //获取jQuery对象(选择器字符串);$("#p1")[0] //转化为DOM对象;$(DOMObj) //转化为j_jq api

ADC学习(2)——频谱性能指标_奈奎斯特区间-程序员宅基地

文章浏览阅读7.8k次,点赞17次,收藏140次。第二章 频谱性能指标_奈奎斯特区间

接口测试-必须掌握的网络基础_b/s 接口测试-程序员宅基地

文章浏览阅读4.6k次,点赞395次,收藏347次。一、网络概述网络是由若干节点和连接这些节点的链路构成,表示诸多对象及其相互联系。在计算机领域中,网络是信息传输、接收、共享的虚拟平台,通过它把各个点、面、体的信息联系到一起,从而实现这些资源的共享。网络是人类发展史来最重要的发明,提高了科技和人类社会的发展。二、网络基础概念客户端:应用 C/S(客户端/服务器) B/S(浏览器/服务器)服务器:为客户端提供服务、数据、资源的机器请求:客户端向服务器索取数据点击免费下载海量工程资料响应:服务器对客户端请求作出反应,一般是返回给客户端数据URL._b/s 接口测试

《Interactive graph cuts for optimal boundary & region segmentation of objects in N-D images》读后感及问题_[1]interactive graph cuts for optimal boundary & r-程序员宅基地

文章浏览阅读4.9k次,点赞3次,收藏10次。N维图像基于最优边界和区域分割的交互式图割用户通过交互式选择图像的某部分作为“目标”和“背景”,然后分割方法基于用户定义的“目标”和“背景”硬性约束,定义一个包含区域和边界信息的能量函数,该能量函数的定义是根据文献[9]MAP-MRF(最大后验概率准则-马尔可夫随机场)定义的,使用能量函数求解达到图像的全局最优的自动分割。而计算机需要达到最优的分割就必须求解该能量函数的最小值,根据[9]可_[1]interactive graph cuts for optimal boundary & region segmentation of obje

vue移动端监听滚动事件实现导航栏上滑隐藏下滑显示功能_vue向下滚动隐藏,向上滚动显示-程序员宅基地

文章浏览阅读2.5k次。场景描述:手机端的顶部导航栏 向上滑动隐藏 向下滑动显示。<script> export default { data(){ return{ i = 0 } }, mounted () { window.addEventListener('scroll', this.handleScroll, true); _vue向下滚动隐藏,向上滚动显示

随便推点

TCP粘包与UDP数据报边界_udp数据边界-程序员宅基地

文章浏览阅读995次。转载:http://blog.csdn.net/lizhifeng2009/article/details/8990844 UDP丢包是因为数据包在传送过程中丢失了 而TCP是基于流式的发送 并且存在丢包重发机制 TCP是可靠连接而UDP是不可靠的这个我就不多说了关于TCP的粘包 正是由于TCP是流式传送的 也就是连接建立后可以一直不停的发送 并没有明确的边界定义 而你用UDP发送的时_udp数据边界

为什么我搭建好的 airtest ios 自动化测试那么慢?_ipad自动化测试慢-程序员宅基地

文章浏览阅读2.6k次。因为 我调通的是ipad ipad 截图 3.1 Miphone 截图 1.6 M之间的差距阻碍实时传图 _ipad自动化测试慢

当摄像头拍摄到识别图时模型显示在识别图上,当摄像头离开识别图时,模型居中显示在屏幕上。...-程序员宅基地

文章浏览阅读250次。using UnityEngine;using System.Collections;using Vuforia;/// <summary>/// 自己重新默认的DefaultTrackableEventHandler脚本(当然你不重写也行,/// 脚本的现实的效果:当摄像头拍摄到识别图时模型显示在识别图上,当摄像头离开识别图时,模型居中显示在屏幕上。/// /// 注意:需..._vuforia物体识别后后上次识别模型居中显示

vue插件 环形进度条动画效果_vue circle-progressbar的用法-程序员宅基地

文章浏览阅读1.4k次。1:首先安装插件 cnpm install vue-circleprogressbar<template> <div class="wrap-progress"> <circle-progressbar :id="1" barColor="#0000ff" backgroundColor="rgba(0,0,0,0.4)" :width="100" _vue circle-progressbar的用法

html+css实现多种动态相册_css动态照片墙-程序员宅基地

文章浏览阅读3.2w次,点赞63次,收藏352次。电子相册全屏背景切换照片墙百叶窗3d照片墙立方体相册代码_css动态照片墙

Sentinel 介绍与使用_sentinel entry exit-程序员宅基地

文章浏览阅读286次。简介Sentinel可以简单的分为Sentinel核心库和Dashboard。核心库不依赖Dashboard,但是结合Dashboard可以取得最好的效果。 核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对Dubbo / Spring Cloud等框架也有较好的支持。 控制台(Dashboard)基于Spring Boot开发,打包后可以直接运行,不需要额外的Tomcat等应用容器。 随着微服务的流行,服务和服务之间的稳定性变得越来越重要。S_sentinel entry exit

推荐文章

热门文章

相关标签