根据灰度值填充字符-单文件单线程版

看到软二的群里,某童鞋发了个自己的java大作业的截图,类似于一个图片,处理后,根据不同的灰度值,填充不同的字符。故,我也用C#来写个玩玩~
首先,图片读入内存,然后- - 有三种处理方式,
第一种是getPixel,然后setPixel。。。
第二种是将图片数据读出,放到byte数组中,然后去读,再copy回去。
第三种是不copy数据,直接在当前图片数据流上操作,然后再解锁就可以了。
由于去年做过类似的工作,所以知道效率问题,第一种。。。速度会很慢(相比较第二种和第三种)。第二种和第三种相差不是很多。但是第三种需要使用unsafe字段。
在这里,我选用第三种进行操作。
界面就不说了。一个按钮,两个pictureBox,一个存原图,一个存字符图。
处理代码如下


代码如下:

private void button1_Click(object sender, EventArgs e)
{
//打开文件
OpenFileDialog open = new OpenFileDialog();
open.Filter = "jpeg图片文件|*.jpg";
if (open.ShowDialog() != DialogResult.OK)
return;
string filePath = open.FileName;
//打开图片,显示原始图
Image img = Image.FromFile(filePath);
sourcePicturebox.Image =img ;
//再次读取一次图潘
Bitmap bitmap = new Bitmap(img);
//锁定图片处理区域
Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
BitmapData bmpData = bitmap.LockBits(rect, ImageLockMode.ReadWrite, bitmap.PixelFormat);
//初始化字符串数组
string[] str = new string[bitmap.Height];
//不安全代码块
unsafe
{
//获取首指针
byte* ptr = (byte*)(bmpData.Scan0);
for (int height = 0; height < bmpData.Height; height++)
{
//由于测试图片是32RGB图,所以,ptr一次移动四位
for (int width = 0; width < bmpData.Width; width++,ptr+=4)
{
str[height] += ((byte)(0.333 * ptr[0] + 0.333 * ptr[1] + 0.333 * ptr[2])) > 128 ? "*" : " ";
}
//为防止图片数据占用不为4的倍数,所以这里用stride,跳过多余的字节
ptr += bmpData.Stride - bmpData.Width * 4;
}
}
//图片解锁
bitmap.UnlockBits(bmpData);
//初始化打印字符参数,以及新建一个空白图片
//空白图片大小。。。。。测试得到的。后续改进
Font font=new System.Drawing.Font ("宋体",20.5f);
Bitmap resultBitmap = new Bitmap(img.Width * 14, img.Height * 14);
Graphics graphics = Graphics.FromImage(resultBitmap);
graphics.Clear(Color.White);
SolidBrush brush=new SolidBrush(Color.Black);
//打印字符,一次一行
for (int i = 0; i < img.Height; i++)
{
graphics.DrawString(str[i], font, brush,0,i*14);
}
//MessageBox.Show(font.GetHeight().ToString());
resultPicturebox.Image = resultBitmap;
//文件保存
SaveFileDialog saveDialog = new SaveFileDialog();
saveDialog.Filter = "jpeg图片文件|*.jpg";
if(saveDialog.ShowDialog()==DialogResult.OK)
resultBitmap.Save(saveDialog.FileName, ImageFormat.Jpeg);
}

实验结果如下
 
实验的结果经过多次调整打印参数,结果还可以。但是,略显紧凑。
***********************************************分隔线******************************************************
小结
由于选的图,是32rgb的,在第一次处理的时候,还有点问题,当成24rgb处理了。。。。出错。。。然后,改后,一开始以为多处的透明分量在低位,结果。。。原来在高位。不过还好最后成功了(其实就试下呗。。。先不处理成字符,而直接改变一个分量为0,然后看效果呗~)

原始图片只有500*500不到,转换后。。。图片为6700+*6700+。。。太大了。。。所以,以后得先处理图片,使其缩小,再进行处理。这里也有二种处理方式,第一是处理原始图像,而是处理那个字符串数组。感觉吧,还是第一种直观些。

然后,后续打印,可以考虑不用string存,而用char[,]来存,这样,又可以用指针了,总觉得指针会快些~
看官可见,上面有一个测试按钮,但是,我没有给出代码,其实那个是用来测试多线程的。打开文件的时候,允许同时选中多个文件,然后操作。这里就用到多线程。但是不知道为何,多线程操作的时候,出来的图片就不对了,如果多线程多了后,还会抛出异常。。。。。就算我就开一个线程,操作一幅图片,也会导致错误的结果。。。所以多线程的代码没有上传,等改好再说吧。

PS.这个改好,估计还要很多天。。。。。毕竟。。。要考试了。。。还是复习去吧。。。前2天在家一点书没看啊。

当然后续改进,不一定就一个多线程,还可以进行字符自定义填充啊(这个简单点)。或者,给个字符串填充额。然后多个灰度级,不同的灰度级给不同的字符填充。再比如。。。可以让它处理所有类型的静态图。。。。(由于那个32RGB的关系。。。特意看了下,还有好多种的。。。)

(0)

相关推荐

  • 根据灰度值填充字符-单文件单线程版

    看到软二的群里,某童鞋发了个自己的java大作业的截图,类似于一个图片,处理后,根据不同的灰度值,填充不同的字符.故,我也用C#来写个玩玩~ 首先,图片读入内存,然后- - 有三种处理方式, 第一种是getPixel,然后setPixel... 第二种是将图片数据读出,放到byte数组中,然后去读,再copy回去. 第三种是不copy数据,直接在当前图片数据流上操作,然后再解锁就可以了. 由于去年做过类似的工作,所以知道效率问题,第一种...速度会很慢(相比较第二种和第三种).第二种和第三种相差

  • Vue单文件组件基础模板小结

    背景 相信大家在使用Vue开发项目时,基本都是以单文件组件的形式开发组件的,这种方式好处多多: 1.代码集中,便于开发.管理和维护 2.可复用性高,直接将vue文件拷贝到新项目中 我暂时就想到这两点,童鞋们可以在评论里帮我补充:因为有这么多优点,所以决定有必要将vue组件的常用配置项提炼出来,形成一个组件模板,方便日后项目开发复用 <template> <div> <h1>{{title}}</h1> <ChildComponents></

  • Vue 单文件中的数据传递示例

    Vue 的单文件组件在使用 Vue 时非常常用,所以我们也会经常遇到组件之间需要传递数据的时候,大致分为三种情况: 父组件向子组件传递数据,通过 props 传递数据. 子组件向父组件传递数据,通过 events 传递数据. 两个同级组件之间传递数据,通过 event bus 传递数据. 文档中也已经详细的说明了各种情况下的解决方法,但是现在我在还没有阅读多少文档的情况下,没有找到有单文件组件方面的具体书写方式,智商和理解能力有限的情况下,自己尝试了一下,最后发现其实是一样的.所以这篇文章其实是

  • Struts2实现单文件或多文件上传功能

    一.简述 Struts2的文件上传其实也是通过拦截器来实现的,只是该拦截器定义为默认拦截器了,所以不用自己去手工配置,<interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/> 二.指定用户上传文件的大小,有两种方式 1)默认是在default.properties 文件的 struts.multipart.maxSize=20

  • Java中使用WebUploader插件上传大文件单文件和多文件的方法小结

    一.使用webuploader插件的原因说明 被现在做的项目坑了. 先说一下我的项目架构spring+struts2+mybatis+MySQL 然后呢.之前说好的按照2G上传就可以了,于是乎,用了ajaxFileUpload插件,因为之前用图片上传也是用这个,所以上传附件的时候就直接拿来用了 各种码代码,测试也测过了,2G文件上传没问题,坑来了,项目上线后,客户又要求上传4G文件,甚至还有20G以上的..纳尼,你不早说哦... 在IE11下用ajaxFileUpload.js插件上传超过4G的

  • asp.net文件上传解决方案(图片上传、单文件上传、多文件上传、检查文件类型)

    小编之前也介绍了许多ASP.NET文件上传的解决案例,今天来个asp.net文件上传大集合. 1 使用标准HTML来进行图片上传 前台代码: <body> <form id="form1" runat="server"> <div> <table> <tr> <td colspan="2" style="height: 21px" > 使用标准HTML来进

  • php封装单文件上传到数据库(路径)

    1.首先思考一个问题上传到数据库是上传的图片还是图片地址这里我们上传的是图片地址,因为图片或音频存数据库中过大,数据库会崩掉. 下面是封装的文件上传的方法: <?php /* *@prame string key *@prame string path *@prame String maxSize *@prame array allowMime *@prame array allowFiletype *@prame bool true * *auther wulei */ function up

  • php表单文件iframe异步上传实例讲解

    本文实例为大家分享了php表单文件iframe异步上传的具体代码,供大家参考,具体内容如下 1.表单中放置iframe元素: 2.文件上传控件内容变化的时候触发JS设置表单的action为处理文件上传的img_upload_process.php文件,并且将表单的target设置为iframe,让iframe去提交到服务器进行文件上传: 3.img_upload_process.php中处理文件上传成功后,将上传成功保存的文件路径回传给表单中隐藏域: 4.点击表单提交按钮的时,JS设置表单act

  • php处理单文件、多文件上传代码分享

    php处理  单文件.多文件上传实例代码,供大家参考,具体内容如下 后台处理文件submit_form_process.php <?php /****************************************************************************** 参数说明: $max_file_size : 上传文件大小限制, 单位BYTE $destination_folder : 上传文件路径 $watermark : 是否附加水印(1为加水印,其他为不加

  • vuejs 单文件组件.vue 文件的使用

    vuejs 自定义了一种.vue文件,可以把html, css, js 写到一个文件中,从而实现了对一个组件的封装, 一个.vue 文件就是一个单独的组件.由于.vue文件是自定义的,浏览器不认识,所以需要对该文件进行解析. 在webpack构建中,需要安装vue-loader 对.vue文件进行解析.在 sumlime 编辑器中,我们 书写.vue 文件,可以安装vue syntax highlight 插件,增加对文件的支持. 用vue-cli 新建一个vue项目,看一下.vue文件长什么样

随机推荐