因为工作需要编写了一个证件照处理程序,但是效率不高,发源代码请大家帮忙指正提高效率

xjw163 2013-05-10 08:26:10
应为工作需要,现有几万张358*441的头像,要将其处理成2*4的一共8张的照片,并将文件名附加在照片下方。
找到几个照相馆都只提供冲印服务,不提供处理照片这一步。不得已自己写程序。程序代码在下。虽然达到了使用要求,但是速度一般,每分钟17张,占内存也比较大。

using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;

namespace ID_photo_processing
{
public partial class Form1 : Form
{
public string FilePath;

public Form1()
{
InitializeComponent();
}
public string GetListBoxItem()
{
string filePath = string.Empty;

bool isSelected = IsListBoxSelected();

if (isSelected == true)
{
string listBoxItemValue = listBox1.SelectedItem.ToString();

filePath = listBoxItemValue;
}
else
{
MessageBox.Show("ListBox must be selected.");
}

return filePath;
}

public bool IsListBoxSelected()
{
bool selected;

if (listBox1.SelectedIndex == -1)//SelectedIndex==-1时,表示未选中任何项。
{
selected = false;
}
else
{
selected = true;
}

return selected;
}

private void listBox1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
e.Effect = DragDropEffects.All;
}
else
{
e.Effect = DragDropEffects.None;
}
}

private void listBox1_DragDrop(object sender, DragEventArgs e)
{
string[] s = (string[])e.Data.GetData(DataFormats.FileDrop, false);

for (int i = 0; i < s.Length; i++)
{
listBox1.Items.Add(s[i]);
}
}

//点击开始处理按钮遍历listBox中的元素进行处理的代码:
private void button1_Click(object sender, EventArgs e)
{
button2.Enabled = false;
textBoxTotal.Text = listBox1.Items.Count.ToString();
textBoxTotal.Refresh();
//问题1:遍历listbox中的元素,有什么办法比较好,我用for实际使用发现占用处理照片越多,占内存越大
for (int i = 0; i < listBox1.Items.Count; i++)
{
startprocess(i);
}
button2.Enabled = true;

}

//开始处理
private void startprocess(int i)
{
//当前在处理的文件计数器
int currentprocess = i + 1;
//当前在处理的文件计数显示
textBoxCurrent.Text = currentprocess.ToString();
textBoxCurrent.Refresh();
//当前在处理的文件路径
string path = listBox1.Items[i].ToString();
//当前在处理的文件名
string filename = System.IO.Path.GetFileNameWithoutExtension(path);
//当前在处理的文件所在文件夹
string filepath = System.IO.Path.GetDirectoryName(path);
DoPhoto(path, filename, filepath);
textBox1.Text = textBox1.Text + path + "处理完毕" + "\r\n";
textBox1.Refresh();
}

//处理照片关键代码 实际使用时速度是每分钟17张 能否换方法提高效率?
private void DoPhoto(string _path,string _filename,string _filepath)
{
string initcolor = "White";
//读取原始文件(要处理的文件)
Bitmap initBitmap = new Bitmap(_path);
//创建空白图像
Bitmap newBitmap = new Bitmap(1512, 1002);
//将图像初始化为白色
for (int i = 0; i < newBitmap.Width; i++)
for (int j = 0; j < newBitmap.Height; j++)
{
Color white = Color.FromName(initcolor);
newBitmap.SetPixel(i, j, white);
}
//读取原始图像,写入到newBitmap中,共写入8次
//理论只读取一次原始照片就好了,但是因为当时不知道如何做,所以用笨办法读了8次,如何做只读取一次?
for (int x = 10; x < 1512; x = x + initBitmap.Width + 20)
for (int y = 10; y < 1002; y = y + initBitmap.Height + 60)
for (int w = 1; w < initBitmap.Width; w++)
for (int h = 1; h < initBitmap.Height; h++)
{
Color color = initBitmap.GetPixel(w, h);
newBitmap.SetPixel(x + w, y + h, color);
}
//给处理后的图像添加文字,即身份证号和姓名
//给照片添加文字有什么比较高效的方法呢?
for (int x = 10; x < 1512; x = x + initBitmap.Width + 20)
for (int y = 10; y < 1002; y = y + initBitmap.Height + 60)
{
Graphics g = Graphics.FromImage(newBitmap);
Font font = new Font("宋体", 18);
SolidBrush sbrush = new SolidBrush(Color.Black);
g.DrawString(_filename, font, sbrush, new PointF(x, y + 441));
MemoryStream ms = new MemoryStream();
}
//保存处理完的文件
newBitmap.Save(_filepath+"\\"+"已处理"+_filename+".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
Refresh();
}

//清空所有文件
private void button2_Click(object sender, EventArgs e)
{
listBox1.Items.Clear();
textBoxTotal.Text = "";
textBoxCurrent.Text = "";
textBox1.Text = "";
}

//关于
private void button3_about_Click(object sender, EventArgs e)
{
MessageBox.Show(@"
针对公司照片处理需求专门编写的程序,
可批量将含有身份证信息的jpg图片文件制作成
2*4张并将身份证号码及姓名附加在照片下方");
}
}
}

...全文
614 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
dylike 2013-05-12
  • 打赏
  • 举报
回复
please_call_me_J 2013-05-11
  • 打赏
  • 举报
回复
引用 13 楼 xjw163 的回复:
[quote=引用 11 楼 juyangjia 的回复:] 没写过图像编程,建议楼主:第一,尝试改为多线程。第二,找点方法尽量降低内存占用 如果楼主愿意,可否将工程打包给我,我有兴趣拿这个来研究下图像编程,如果我熟悉了耶就能帮你改掉这个效率问题了
当然可以啊,加qq交流254I42972[/quote]楼主,你的QQ中间为什么有个字母“I”啊。。。。求解释
xjw163 2013-05-11
  • 打赏
  • 举报
回复
引用 27 楼 juyangjia 的回复:
[quote=引用 13 楼 xjw163 的回复:] [quote=引用 11 楼 juyangjia 的回复:] 没写过图像编程,建议楼主:第一,尝试改为多线程。第二,找点方法尽量降低内存占用 如果楼主愿意,可否将工程打包给我,我有兴趣拿这个来研究下图像编程,如果我熟悉了耶就能帮你改掉这个效率问题了
当然可以啊,加qq交流254I42972[/quote]楼主,你的QQ中间为什么有个字母“I”啊。。。。求解释[/quote]I代表1 反搜索引擎用的
xjw163 2013-05-11
  • 打赏
  • 举报
回复
引用 27 楼 juyangjia 的回复:
[quote=引用 13 楼 xjw163 的回复:] [quote=引用 11 楼 juyangjia 的回复:] 没写过图像编程,建议楼主:第一,尝试改为多线程。第二,找点方法尽量降低内存占用 如果楼主愿意,可否将工程打包给我,我有兴趣拿这个来研究下图像编程,如果我熟悉了耶就能帮你改掉这个效率问题了
当然可以啊,加qq交流254I42972[/quote]楼主,你的QQ中间为什么有个字母“I”啊。。。。求解释[/quote]I代表1 反搜索引擎用的
xjw163 2013-05-10
  • 打赏
  • 举报
回复
有人帮忙看看不啊
xjw163 2013-05-10
  • 打赏
  • 举报
回复
我也想用你说的方法,但无奈之时水平有限做不到,能提供一些这方面的资料吗
Trent1985 2013-05-10
  • 打赏
  • 举报
回复
你不要使用setPixel()这个方法,这个严重影响处理速度,是实时图像处理中的忌讳,给你个地址看下,一般都是把图像读入内存,或者使用指针处理的,速度比setPixel快几个数量级。http://dongtingyueh.blog.163.com/
xjw163 2013-05-10
  • 打赏
  • 举报
回复
楼上误解了,是原始照片的分辨率是258*441的单张,现在处理成打印在相纸上的8小张,不知我说的清楚不
Trent1985 2013-05-10
  • 打赏
  • 举报
回复
358*441的头像,要将其处理成2*4?这么小?能看到吗?。。。。
xjw163 2013-05-10
  • 打赏
  • 举报
回复
照片穿不上来,请移步

http://tieba.baidu.com/p/2318411378
xjw163 2013-05-10
  • 打赏
  • 举报
回复
引用 23 楼 sj178220709 的回复:
猫咪太萌了。感谢你的指点。程序已达到使用需求。我在24楼提出了新问题,希望不吝赐教!
xjw163 2013-05-10
  • 打赏
  • 举报
回复
感谢楼上各位的指点,此贴基本可以结贴了。 目前我这个程序的最终版本见下,程序的速度和内存占用都比初始版本有极大的提升,完全达到了使用需求,不再改进了

using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;

namespace ID_photo_processing
{
    public partial class Form1 : Form
    {
        public string FilePath;

        public Form1()
        {
            InitializeComponent();
        }
        public string GetListBoxItem()
        {
            string filePath = string.Empty;

            bool isSelected = IsListBoxSelected();

            if (isSelected == true)
            {
                string listBoxItemValue = listBox1.SelectedItem.ToString();

                filePath = listBoxItemValue;
            }
            else
            {
                MessageBox.Show("ListBox must be selected.");
            }

            return filePath;
        }

        public bool IsListBoxSelected()
        {
            bool selected;

            if (listBox1.SelectedIndex == -1)//SelectedIndex==-1时,表示未选中任何项。
            {
                selected = false;
            }
            else
            {
                selected = true;
            }

            return selected;
        }

        private void listBox1_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.All;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }

        private void listBox1_DragDrop(object sender, DragEventArgs e)
        {
            string[] s = (string[])e.Data.GetData(DataFormats.FileDrop, false);

            for (int i = 0; i < s.Length; i++)
            {
                listBox1.Items.Add(s[i]);
            }
        }

        //点击开始处理按钮遍历listBox中的元素进行处理的代码:
        private void button1_Click(object sender, EventArgs e)
        {
            button2.Enabled = false;
            textBoxTotal.Text = listBox1.Items.Count.ToString();
            textBoxTotal.Refresh();
            //for (int i = 0; i < listBox1.Items.Count; i++)
            //{
            //    startprocess(i);

            //}
            int i = 0;
            foreach (string path in listBox1.Items)
            {
                string filename = System.IO.Path.GetFileNameWithoutExtension(path);
                string filepath = System.IO.Path.GetDirectoryName(path);
                DoPhoto(path, filename, filepath);
                textBox1.Text = textBox1.Text + path + "处理完毕" + "\r\n";
                //textBox1.Text = textBox1.Text + path + DateTime.Now.ToString("hh:mm:ss");
                textBox1.Refresh();
                i= i + 1;
                textBoxCurrent.Text = i.ToString();
                textBoxCurrent.Refresh();
            }
            button2.Enabled = true;
            MessageBox.Show("处理完毕");
            
        }

        //处理照片关键代码
        private void DoPhoto(string _path,string _filename,string _filepath)
        {
            //读取原始文件(要处理的文件)
            Bitmap initBitmap = new Bitmap(_path);
            //创建空白图像
            Bitmap newBitmap = new Bitmap(1512, 1002);
            Graphics newjpg = Graphics.FromImage(newBitmap);
            newjpg.Clear(Color.White);
            //初始化字体
            Font font = new Font("宋体", 18);
            SolidBrush sbrush = new SolidBrush(Color.Black);
            for (int x = 10; x < 1512; x = x + initBitmap.Width + 20)
                for (int y = 10; y < 1002; y = y + initBitmap.Height + 60)
                {
                    newjpg.DrawImage(initBitmap, x, y, 358, 441);
                    newjpg.DrawString(_filename, font, sbrush, new PointF(x, y + 446));
                }
            //保存处理完的文件
            newBitmap.Save(_filepath+"\\"+"已处理"+_filename+".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
            initBitmap.Dispose();
            newBitmap.Dispose();
            newjpg.Dispose();
            Refresh();
        }

        //清空所有文件
        private void button2_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
            textBoxTotal.Text = "";
            textBoxCurrent.Text = "";
            textBox1.Text = "";
        }
就是还有个问题想再请教一下,为何点击开始处理按钮后,前几十张的时候程序还能响应,往后程序就挂起了呢?虽然挂起了,但是照片其实还是在正常处理中的。如何解决这个问题?让程序不论处理多少张照片都运算自如,不被挂起呢?
xjw163 2013-05-10
  • 打赏
  • 举报
回复
CSDN怎么上传不了照片?!烦躁!
_小黑_ 2013-05-10
  • 打赏
  • 举报
回复
感谢分享 支持一下
liuyilin999 2013-05-10
  • 打赏
  • 举报
回复
  • 打赏
  • 举报
回复
  • 打赏
  • 举报
回复
 public static void GetNewMap(string path)
        {
            Bitmap b1 = new Bitmap(path);
            int width = b1.Width, height = b1.Height;
            //设置好需要的宽高
            Bitmap b = new Bitmap(width*4 + 16, height*2 + 4);
            //取得画刷
            Graphics g = Graphics.FromImage(b);
            //画八张图
            for (int i = 0; i < 4; i++)
            {
                g.DrawImage(b1, (width + 2)*i, 0);
                g.DrawImage(b1, (width + 2)*i, height + 2);
            }

            //把合并后的位图保存到文件流中 
            int tempHigh = b1.Height;
            FileStream fs = new FileStream("e:\\result.jpg", FileMode.Create);

            b.Save(fs, ImageFormat.Jpeg);
            fs.Flush();
            fs.Close();
        }
  • 打赏
  • 举报
回复
public static void GetNewMap(string path) { Bitmap b1 = new Bitmap(path); int width = b1.Width, height = b1.Height; //设置好需要的宽高 Bitmap b = new Bitmap(width*4 + 16, height*2 + 4); //取得画刷 Graphics g = Graphics.FromImage(b); //画八张图 for (int i = 0; i < 4; i++) { g.DrawImage(b1, (width + 2)*i, 0); g.DrawImage(b1, (width + 2)*i, height + 2); } //把合并后的位图保存到文件流中 int tempHigh = b1.Height; FileStream fs = new FileStream("e:\\result.jpg", FileMode.Create); b.Save(fs, ImageFormat.Jpeg); fs.Flush(); fs.Close(); } 临时写了一个 完全满足楼主的要求 而且应该是基本不存在性能问题的。
SimonYeung 2013-05-10
  • 打赏
  • 举报
回复
不错 学习下 用着的
  • 打赏
  • 举报
回复
楼主这是一个一个像素点去重绘啊,能不慢么? 直接新建一个bitmap 用画刷在上面画8次原来的bitmap就ok了, 几乎不会有什么性能问题。
加载更多回复(9)
[本课程属于AI完整学习路线套餐,该套餐已“硬核”上线,点击立即学习!] 【为什么要学习深度学习和计算机视觉?】 AI人工智能现在已经成为人类展中最火热的领域。而计算机视觉(CV)是AI中最热门,也是落地最多的一个应用方向(人脸识别,自动驾驶,智能安防,车牌识别,证件识别)。所以基于人工智能的计算视觉行业必然会诞生大量的工作和创业的机会。如何能快速的进入CV领域,同时兼备理论基础和实战能力,就成了大多数学习者关心的事情,而这门课就是因为这个初衷而设计的。 【讲师介绍】 CHARLIE 老师 1、人工智能算法科学家2、深圳市海外高层次人才认定(孔雀人才)3、美国圣地亚哥国家超算中心博士后4、加利福尼亚大学圣地亚哥全奖博士5、参与美国自然科学基金(NSF)及加州能源局 (CEC)资助的392MWIVANPAH等智慧电网项目6、21篇国际期刊文章(sci收录17篇),总引用接近10007、第一作者明专利11份【推荐你学习这门课的理由:知识体系完整+丰富学习资料】 1、本课程总计9大章节,是一门系统入门计算机视觉的课程,未来将持续更新。2、课程从计算机视觉理论知识出,理论结合实战,手把手的实战代码实现(霍夫变换与模板匹配,AlexNet OCR应用,VGG迁移学习,多标签分类算法工程) 3、带你了解最前沿技术,各类型算法的优点和缺点,掌握数据增强,Batchnormalization, Dropout,迁移学习等优化技巧,搭建实用的深度学习应用模型 4、学习完后,你将具有深度学习与计算视觉的项目能力,比如大学生学完可以具备独立完成机器视觉类毕业设计的能力,在求职过程中可以体系化的讲解机器视觉核心知识点,初步达到人工智能领域机器视觉工程师的水平 【学完后我将达到什么水平?】 1、零基础入门计算视觉,学习掌握并应用从经典图像处理到深度学习分类任务的要点知识 2、掌握数据增强,迁移学习等优化技巧,搭建实用的深度学习应用模型 3、学习完课程,可以独立应用多个经典算法和深度学习算法 4、以大学毕业设计,面试找工作为目标,手把手带大家编程,即使没有太多计算视觉的背景知识也可以循序渐进完成课程,获得实战项目的经验 【面向人群】 1、对AI感兴趣,想要系统学习计算机视觉的学员 2、需要毕业设计的大学生 3、做图像分析或相关数据分析的研究生 4、准备面试计算视觉和深度学习岗位的应聘者 5、希望在项目中引入计算视觉/深度学习技术的开人员 【课程知识体系图】 【实战项目】

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧