NET二进制图片存储与读取的常见方法,iTextSharp添加图片生成PDF文件
public void iTextSharpCreatPDF()
{
string pdfpath = System.Web.HttpContext.Current.Server.MapPath("~/log/DPD/");
string imagepath = System.Web.HttpContext.Current.Server.MapPath("~/log/DPD/");
Document doc = new Document(new Rectangle(, ), , , , ); //new Rectangle(1000,1000)
//指定文件预设开档时的缩放为100%
//PdfDestination pdfDest = new PdfDestination(PdfDestination.XYZ, 0, doc.PageSize.Height, 1f);
try
{
PdfWriter.GetInstance(doc, new FileStream(pdfpath + "/DPD_15505984238198.pdf", FileMode.Create));
doc.Open(); //下面对图片进行操作
Image image = Image.GetInstance(imagepath + "/DPD_15505984238198.jpg");
float percentage = ;
//这里都是图片最原始的宽度与高度
float resizedWidht = image.Width;
float resizedHeight = image.Height; ////这时判断图片宽度是否大于页面宽度减去也边距,如果是,那么缩小,如果还大,继续缩小,
////这样这个缩小的百分比percentage会越来越小
//while (resizedWidht > (doc.PageSize.Width - doc.LeftMargin - doc.RightMargin) * 0.8)
//{
// percentage = percentage * 0.9f;
// resizedHeight = image.Height * percentage;
// resizedWidht = image.Width * percentage;
//}
////There is a 0.8 here. If the height of the image is too close to the page size height,
////the image will seem so big
//while (resizedHeight > (doc.PageSize.Height - doc.TopMargin - doc.BottomMargin) * 0.8)
//{
// percentage = percentage * 0.9f;
// resizedHeight = image.Height * percentage;
// resizedWidht = image.Width * percentage;
//} ////这里用计算出来的百分比来缩小图片
image.ScalePercent(percentage * );
//让图片的中心点与页面的中心店进行重合
image.SetAbsolutePosition(doc.PageSize.Width / - resizedWidht / , doc.PageSize.Height / - resizedHeight / );
doc.Add(image); }
catch (DocumentException dex)
{
System.Web.HttpContext.Current.Response.Write(dex.Message);
}
catch (IOException ioex)
{
System.Web.HttpContext.Current.Response.Write(ioex.Message);
} catch (Exception ex)
{
System.Web.HttpContext.Current.Response.Write(ex.Message);
}
finally
{
doc.Close();
}
}
.NET二进制图片存储:以二进制的形式存储图片时,要把数据库中的字段设置为Image数据类型(SQL Server),存储的数据是Byte[].
.参数是图片路径:返回Byte[]类型: .public byte[] GetPictureData(string imagepath)
. {
. //根据图片文件的路径使用文件流打开,并保存为byte[]
. FileStream fs = new FileStream(imagepath, FileMode.Open);
. byte[] byData = new byte[fs.Length];
. fs.Read(byData, , byData.Length);
. fs.Close();
. return byData;
. }
. .参数类型是Image对象,返回Byte[]类型: .public byte[] PhotoImageInsert(System.Drawing.Image imgPhoto)
. {
. //将Image转换成流数据,并保存为byte[]
. MemoryStream mstream = new MemoryStream();
. imgPhoto.Save(mstream, System.Drawing.Imaging.ImageFormat.Bmp);
. byte[] byData = new Byte[mstream.Length];
. mstream.Position = ;
. mstream.Read(byData, , byData.Length);
. mstream.Close();
. return byData;
. } 好了,这样通过上面的方法就可以把图片转换成Byte[]对象,然后就把这个对象保存到数据库中去就实现了把图片的二进制格式保存到数据库中去了。下面我就谈谈如何把数据库中的图片读取出来,实际上这是一个相反的过程。
.NET二进制图片读取:把相应的字段转换成Byte[]即:Byte[] bt=(Byte[])XXXX
.参数是Byte[]类型,返回值是Image对象: .public System.Drawing.Image ReturnPhoto(byte[] streamByte)
. {
. System.IO.MemoryStream ms = new System.IO.MemoryStream(streamByte);
. System.Drawing.Image img = System.Drawing.Image.FromStream(ms);
. return img;
. } .参数是Byte[] 类型,没有返回值,这是针对asp.net中把图片从输出到网页上(Response.BinaryWrite) .public void WritePhoto(byte[] streamByte)
. {
. // Response.ContentType 的默认值为默认值为“text/html”
. Response.ContentType = "image/GIF";
. //图片输出的类型有: image/GIF image/JPEG
. Response.BinaryWrite(streamByte);
. } 补充:
针对Response.ContentType的值,除了针对图片的类型外,还有其他的类型: .Response.ContentType = "application/msword";
. Response.ContentType = "application/x-shockwave-flash";
. Response.ContentType = "application/vnd.ms-excel"; 另外可以针对不同的格式,用不同的输出类型以适合不同的类型:
.switch (dataread("document_type"))
. {
. case "doc":
. Response.ContentType = "application/msword";
. case "swf":
. Response.ContentType = "application/x-shockwave-flash";
. case "xls":
. Response.ContentType = "application/vnd.ms-excel";
. case "gif":
. Response.ContentType = "image/gif";
. case "Jpg":
. Response.ContentType = "image/jpeg";
. } protected void Button1_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
Stream mystream = FileUpload1.PostedFile.InputStream;//FileUpload1是上传控件..
int length = FileUpload1.PostedFile.ContentLength;
byte[] bytes = new byte[length];
mystream.Read(bytes, , length);
mystream.Close();
string conn = "server=(local);database=Image;Uid=sa;Pwd=123456 ";
SqlConnection myconn = new SqlConnection(conn);
myconn.Open();
string str= "insert into image (img) values( ' " + bytes + " ') ";
SqlCommand mycomm = new SqlCommand(str, myconn);
mycomm.ExecuteNonQuery();
myconn.Close();
}
}
上面把图片存入数据库...
下面是把图片从数据库中读出来...
protected void Button2_Click(object sender, EventArgs e)
{
string imgtype = FileUpload1.PostedFile.ContentType;
string conn = "server=(local);database=Image;Uid=sa;Pwd=123456 ";
string str= "select img from image where ID=5 ";
SqlConnection myconn = new SqlConnection(conn);
myconn.Open();
//SqlDataAdapter myda = new SqlDataAdapter(str, conn);
//DataSet myds =new DataSet();
//myda.Fill(myds);
SqlCommand mycom = new SqlCommand(str, myconn);
SqlDataReader mydr = mycom.ExecuteReader();
if (mydr.Read())
{
Response.ContentType = imgtype;
Response.BinaryWrite((byte[])mydr[ "img "]);
}
else
{
Response.Write( "没有从数据库中读取图片 ");
}
myconn.Close();
} 一、发生的背景
在开发新项目中使用了新的语言开发C#和新的技术方案WEB Service,但是在新项目中,一些旧的模块需要继续使用,一般是采用C或C++或Delphi编写的,如何利用旧模块对于开发人员来说,有三种可用方法供选择:第一、将C或C++函数用C#彻底改写一遍,这样整个项目代码比较统一,维护也方便一些。但是尽管微软以及某些书籍说,C#和C++如何接近,但是改写起来还是很痛苦的事情,特别是C++里的指针和内存操作;第二、将C或C++函数封装成COM,在C#中调用COM比较方便,只是在封装时需要处理C或C++类型和COM类型之间的转换,也有一些麻烦,另外COM还需要注册,注册次数多了又可能导致混乱;第三、将C或C++函数封装成动态链接库,封装的过程简单,工作量不大。因此我决定采用加载动态链接库的方法实现,于是产生了在C#中如何调用自定义的动态链接库问题,我在网上搜索相关主题,发现一篇调用系统API的文章,但是没有说明如何解决此问题,在MSDN上也没有相关详细说明。基于此,我决定自己从简单出发,逐步试验,看看能否达到自己的目标。
(说明一点:我这里改写为什么很怕麻烦,我改写的代码是变长加密算法函数,代码有600多行,对算法本身不熟悉,算法中指针和内存操作太多,要想保证算法正确,最可行的方法就是少动代码,否则只要有一点点差错,就不能肯定算法与以前兼容) 二、技术实现
下面看看如何逐步实现动态库的加载,类型的匹配: 动态链接库函数导出的定义,这个不需要多说,大家参考下面宏定义即可:
#define LIBEXPORT_API extern "C" __declspec(dllexport) 第一步,我先从简单的调用出发,定义了一个简单的函数,该函数仅仅实现一个整数加法求和:
LIBEXPORT_API int mySum(int a,int b){ return a+b;} C#定义导入定义:
public class RefComm
{
[DllImport("LibEncrypt.dll", EntryPoint=" mySum ",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)] public static extern int mySum (int a,int b);
} 在C#中调用测试:
int iSum= RefComm. mySum(,);
运行查看结果iSum为5,调用正确。第一步试验完成,说明在C#中能够调用自定义的动态链接库函数。 第二步,我定义了字符串操作的函数(简单起见,还是采用前面的函数名),返回结果为字符串:
LIBEXPORT_API char *mySum(char *a,char *b){sprintf(b,”%s”,a) return a;} C#定义导入定义:
public class RefComm
{
[DllImport("LibEncrypt.dll", EntryPoint=" mySum ",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)] public static extern string mySum (string a, string b);
} 在C#中调用测试:
string strDest=””;
string strTmp= RefComm. mySum(“”, strDest);
运行查看结果strTmp为“”,但是strDest为空。 我修改动态链接库实现,返回结果为串b:
LIBEXPORT_API char *mySum(char *a,char *b){sprintf(b,”%s”,a) return b;} 修改C#导入定义,将串b修改为ref方式:
public class RefComm
{
[DllImport("LibEncrypt.dll", EntryPoint=" mySum ",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)] public static extern string mySum (string a, ref string b);
}
在C#中再调用测试:
string strDest=””;
string strTmp= RefComm. mySum(“”, ref strDest);
运行查看结果strTmp和strDest均不对,含不可见字符。 再修改C#导入定义,将CharSet从Auto修改为Ansi:
public class RefComm
{
[DllImport("LibEncrypt.dll", EntryPoint=" mySum ",CharSet=CharSet.Ansi,CallingConvention=CallingConvention.StdCall)] public static extern string mySum (string a, string b);
}
在C#中再调用测试:
string strDest=””;
string strTmp= RefComm. mySum(“”, ref strDest);
运行查看结果strTmp为“”,但是串strDest没有赋值。第二步实现函数返回串,但是在函数出口参数中没能进行输出。 再次修改C#导入定义,将串b修改为引用(ref):
public class RefComm
{
[DllImport("LibEncrypt.dll", EntryPoint=" mySum ",CharSet=CharSet.Ansi,CallingConvention=CallingConvention.StdCall)] public static extern string mySum (string a, ref string b);
}
运行时调用失败,不能继续执行。 第三步,修改动态链接库实现,将b修改为双重指针:
LIBEXPORT_API char *mySum(char *a,char **b){sprintf((*b),”%s”,a) return *b;} C#导入定义:
public class RefComm
{
[DllImport("LibEncrypt.dll", EntryPoint=" mySum ",CharSet=CharSet.Ansi,CallingConvention=CallingConvention.StdCall)] public static extern string mySum (string a, ref string b);
} 在C#中调用测试:
string strDest=””;
string strTmp= RefComm. mySum(“”, ref strDest);
运行查看结果strTmp和strDest均为“”,调用正确。第三步实现了函数出口参数正确输出结果。 第四步,修改动态链接库实现,实现整数参数的输出:
LIBEXPORT_API int mySum(int a,int b,int *c){ *c=a+b; return *c;} C#导入的定义:
public class RefComm
{
[DllImport("LibEncrypt.dll", EntryPoint=" mySum ",CharSet=CharSet.Ansi,CallingConvention=CallingConvention.StdCall)] public static extern int mySum (int a, int b,ref int c);
} 在C#中调用测试:
int c=;
int iSum= RefComm. mySum(,, ref c);
运行查看结果iSum 和c均为5,调用正确。 经过以上几个步骤的试验,基本掌握了如何定义动态库函数以及如何在C#定义导入,有此基础,很快我实现了变长加密函数在C#中的调用,至此目标实现。 三、结论
在C#中,调用C++编写动态链接库函数,如果需要出口参数输出,则需要使用指针,对于字符串,则需要使用双重指针,对于C#的导入定义,则需要使用引用(ref)定义。
对于函数返回值,C#导入定义和C++动态库函数申明定义需要保持一致,否则会出现函数调用失败。
定义导入时,一定注意CharSet和CallingConvention参数,否则导致调用失败或结果异常。
运行时,动态链接库放在C#程序的目录下即可,我这里是一个C#的动态链接库,两个动态链接库就在同一个目录下运行。
NET二进制图片存储与读取的常见方法,iTextSharp添加图片生成PDF文件的更多相关文章
- [轉載]史上最强php生成pdf文件,html转pdf文件方法
之前有个客户需要把一些html页面生成pdf文件,然后我就找一些用php把html页面围成pdf文件的类.方法是可谓是找了很多很多,什么html2pdf,pdflib,FPDF这些都试过了,但是都没有 ...
- 史上最强php生成pdf文件,html转pdf文件方法
body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...
- PDF怎样添加注释,PDF文件添加注释的方法
Word文件跟纸质文件想要添加注释相信大家都知道该怎么添加,那么现在也使用频率挺高的PDF格式的文件要怎么添加注释呢?添加注释的方法有什么呢?有许多的小伙伴们都想知道吧,今天小编就来跟大家分享一下,想 ...
- 编辑方法分享之如何编辑PDF文件内容
我们现在在工作中会经常使用到PDF文件,还会有遇到需要编辑PDF文件的时候,PDF文件的编辑问题一直是个大难题.很多朋友在面对PDF文件的时候束手无策,不知道该怎么对它进行编辑.下面小编就教给大家一个 ...
- 前端axios请求二进制数据流转换生成PDF文件空白问题(终极解决方案)
本文章共1570字,预计阅读时间1 - 3分钟. 问题场景: axios请求二进制数据转换生成PDF空白问题,使用axios请求后端接口,后端返回的二进制流文件,需要转换成PDF,但是在postman ...
- 关于java poi itext生成pdf文件的例子以及方法
最近正在做导出pdf文件的功能,所以查了了一些相关资料,发现不是很完善,这里做一些小小的感想,欢迎各位“猿”童鞋批评指正. poi+itext,所需要的jar包有itext-2.1.7.jar,poi ...
- 一个Itextsharp 批量添加图片到pdf 方法
这里我就直接把我的页面贴进来了 using System; using System.Collections.Generic; using System.Web; using System.Web.U ...
- asp.net 生成PDF方法
今天转博客园看到有人发表了一篇生成PFd的文章,准备自己也留一份准备以后用到的时候方便调用: 首先去itextsharp网站下载控件(https://sourceforge.net/projects/ ...
- TensorFlow高效读取数据的方法——TFRecord的学习
关于TensorFlow读取数据,官网给出了三种方法: 供给数据(Feeding):在TensorFlow程序运行的每一步,让python代码来供给数据. 从文件读取数据:在TensorFlow图的起 ...
随机推荐
- 转:CMake快速入门教程-实战
CMake快速入门教程:实战 收藏人:londonKu 2012-05-07 | 阅:10128 转:34 | 来源 | 分享 0. 前言一个多月 ...
- 微信扫码支付springboot版本
发布时间:2018-11-06 技术:springboot+freemarker 概述 该项目是一个采用springboot构建的web项目,主要实现了微信扫码支付功能.包含最基本的创建订单, ...
- 安全删除linux旧内核的方法
我们在用yum升级系统之后,希望往往会为我们保持旧的内核文件,这样以防在出现硬件或者软件冲突的时候我们能够返回到旧的内核文件继续使用,如果我们想要安全的删除旧的内核文件,可以follow下面的方法. ...
- jsp页面如何读取从后台传来的json
===================================问====================================== var obj = jQuery.parseJSO ...
- linux shell 脚本攻略学习10--生成任意大小的文件和文本文件的交集与差集详解
一.生成任意大小的文件(dd命令): 举例: amosli@amosli-pc:~/learn/example$ ; + records in + records out bytes ( MB/s a ...
- ipsec协议(转)
from:http://lulu1101.blog.51cto.com/4455468/816875 ipsec协议 2012-03-25 23:40:28 标签:休闲 ipsec协议 职场 IPSe ...
- Android上实现MVP模式的途径
今天我想分享我在Android上实现MVP(Model-View-Presenter)模式的方法.如果你对MVP模式还不熟悉,或者不了解为什么要在Android应用中使用MVP模式,推荐你先阅读这篇维 ...
- android dialog加载中动画效果
//显示动画 dialog = new Dialog(context, R.style.loading); dialog.setContentView(R.layout.loadinglayout); ...
- 【java】解析java中的数组
目录结构: contents structure [+] 一维数组 1,什么是一维数组 2,声明一维数组的三种方式 二维数组 1,什么是二维数组 2,声明二维数组的3种方式 3,二维数组的遍历示例 数 ...
- Docker K8s基本概念入门
原文地址:https://blog.csdn.net/TM6zNf87MDG7Bo/article/details/79621510 k8s是一个编排容器的工具,其实也是管理应用的全生命周期的一个工具 ...