Share via


How to add image from local disk to crystal report 2008

Question

Sunday, October 26, 2014 8:54 AM

Hi guys i have proplem
I create crystal report(blank report) to show the data of employee from database hrdata on table Employee based on stored procedure
his name is ShowEmployee
when he write EmployeeNo in textbox1 control show employee detailes
as name,address,nationality,branch,join date,birth date,personal picture
but personal picture field not exist in database so that i need to show the picture from local
path from local hard disk
Meaning when i write in textbox1 employee no as 1233 show
1- detailes from database and that i already done
2-show image from local hard disk based on textbox1 (employee no) not done
i need code by c# to show image in crystal report from local drive based on employee no
how i do that
using System;
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.Configuration;
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.ReportSource;
using CrystalDecisions.Shared;
using CrystalDecisions.Windows.Forms;

namespace FleetManagment
{
    public partial class ShowEmployeeRecord : Form
    {
       
        public ShowEmployeeRecord()
        {
            InitializeComponent();
           
        }
private Reports.DateBaseReport objMyReport;      
private ConnectionInfo objConnectionInfo;     
private void setSQLParams()
{
ParameterField objParameterField =
crystalReportViewer1.ParameterFieldInfo[0];
ParameterDiscreteValue objParameterDiscreteValue;
objParameterDiscreteValue = new ParameterDiscreteValue();
objParameterDiscreteValue.Description = "@EmployeeNo";
objParameterDiscreteValue.Value = Convert.ToDateTime (textbox1.text);
objParameterField.CurrentValues.Add(objParameterDiscreteValue);
crystalReportViewer1.ParameterFieldInfo.Add(objParameterField);
objParameterField = crystalReportViewer1.ParameterFieldInfo[1];
}

private void setDatabaseSettings()
{
objConnectionInfo = new ConnectionInfo();
objConnectionInfo.ServerName = "192.168.1.5";
objConnectionInfo.DatabaseName = "hrdata";
objConnectionInfo.UserID = "sa";
objConnectionInfo.Password = "1234";
}

private void refreshReport()
{          
Tables tables =Tables tables = objMyReport.Database.Tables;
foreach (Table tbl in tables)
{
TableLogOnInfo objTableLogOnInfo = new TableLogOnInfo();
objTableLogOnInfo.ConnectionInfo = objConnectionInfo;
tbl.ApplyLogOnInfo(objTableLogOnInfo);
}        
crystalReportViewer1.ReportSource = objMyReport;         
setSQLParams();
}

private void crystalReportViewer1_ReportRefresh(object source, CrystalDecisions.Windows.Forms.ViewerEventArgs e)
{
e.Handled = true;         
((ReportClass)crystalReportViewer1.ReportSource).Refresh();  
}

private void button2_Click(object sender, EventArgs e)
{
objMyReport = new Reports.DateBaseReport();       
setDatabaseSettings();        
refreshReport();

}
}
}

All replies (22)

Monday, October 27, 2014 8:27 PM ✅Answered

Thank you for reply

i try the code above

post before above it work as following

  DataTable dt = new DataTable();
            string connString = "data source=192.168.1.5; initial catalog=hrdata;uid=sa; password=1234";
            using (SqlConnection con = new SqlConnection(connString))
            {
                con.Open();
                SqlCommand cmd = new SqlCommand("ViewEmployeeNoR", con);
                cmd.CommandType = CommandType.StoredProcedure;    // Viewxxx doesn't seem a good name for a sp
                cmd.Parameters.Add("@EmployeeNo", SqlDbType.NVarChar, 20);
                cmd.Parameters["@EmployeeNo"].Value = textBox1.Text;
                SqlDataAdapter da = new SqlDataAdapter();
                da.SelectCommand = cmd;
                da.Fill(dt);
            }
            dt.Columns.Add("Image", System.Type.GetType("System.Byte[]"));

            string path = Path.Combine("\\192.168.1.5\Personal Pictures", textBox1.Text) + ".jpg";
            FileStream fs;
            if (File.Exists(path))
            {
               fs = new FileStream("\\192.168.1.5\Personal Pictures\" + textBox1.Text + ".jpg", FileMode.Open);
            }
            else
            {

                MessageBox.Show("Please File Not Exist");

            }

            BinaryReader br = new BinaryReader(fs);
            byte[] imgbyte = new byte[fs.Length + 1];
            imgbyte = br.ReadBytes(Convert.ToInt32((fs.Length)));

            foreach (DataRow dr  in dt.Rows)
            {
                dr["Image"] = imgbyte;
            }
            ReportDocument objRpt = new Reports.CrystalReportData1();
            objRpt.SetDataSource(dt);
            crystalReportViewer1.ReportSource = objRpt;
            crystalReportViewer1.Refresh();

but i add image in database then add in datatable then drag and put in crystal report

and i comment this line

// dt.Columns.Add("Image", System.Type.GetType("System.Byte[]"));

are this what you mean and why i write this line


Tuesday, October 28, 2014 8:10 AM ✅Answered

Good to hear you got it working.

1)

You'll know which is what as you go get the data.  Give your classes and methods  meaningful names and you'll know which is what.

Deal with each report separately.

The code will only have scope for one table in one dataset, it won't be a problem.

2)

I'm not sure I follow this question.

The crystal report definition is fixed when you design it.

It needs to know it's going to get an image from somewhere.

You can drag an image on, or (I think) you can have a column you're designing against which is a blob(picture) and drag that onto the design surface.

You're substituting where it's coming from.


Sunday, October 26, 2014 10:25 AM

Can any one help me in answer this question if possible


Sunday, October 26, 2014 10:31 AM

Rather than using crystal to go read data, you are better getting the data yourself and presenting it to crystal.  So long as the field names and types match, you can substitute a datatable or whatever at run time.

.

As to your question.

Insert an image field in your report.

Right click>Insert>Picture Choose any old picture

BUT of the size you're expecting.

Right click your new picture once it's in the report.

Format picture > picture tab

Click the formula button ( with x-2 and a pen on it ) in the Graphic box 

Choose a field or parameter which will contain the image URI


Sunday, October 26, 2014 10:52 AM

Thank you for reply

But i dont need one picture or fixed picture 

what i need is to get picture for every employee

suppose i have 6 picture

1,2,3,4,5,6 and every number has picture

if i write 1 in textbox1 give me picture for 1 from local drive

if i write 2 in textbox1 give me picture for 2 from local drive

as above for every employee


Sunday, October 26, 2014 10:56 AM

Follow my advice.

The uri will make it go read the uri you provide at run time.

Don't get stuck on the fact there's one picture there at design time.


Sunday, October 26, 2014 11:00 AM

Can you show me this way more clear if possible please 

i make right click and insert picture

but i don't know from which place i can get formula

i reached until this


Sunday, October 26, 2014 11:10 AM

can you help me


Sunday, October 26, 2014 11:21 AM

I don't have vs2008 available.

In the current version of crystal reports the formula is on that tab.

Maybe it's elsewhere in older versions.  It's a long time since I used the version in vs2008 so I'm afraid I can't be specific.

Look through the other tabs.

Maybe you could use the current version of sap crystal reports with vs2008.

http://scn.sap.com/docs/DOC-7824

If there simply isn't the option then you could build your own datatable and merge the picture in.

Or supply it as a parameter.

http://www.codeproject.com/Articles/21095/Image-in-Crystal-Reports

This bit is reading the file off disk and adding to a datatable:

        if (File.Exists(AppDomain.CurrentDomain.BaseDirectory + "10157.Jpg")) { 
            // open image in file stream 
            fs = new FileStream(AppDomain.CurrentDomain.BaseDirectory + "10157.Jpg", FileMode.Open); 
        } 
        else { 
            // if phot does not exist show the nophoto.jpg file 
            fs = new FileStream(AppDomain.CurrentDomain.BaseDirectory + "NoPhoto.jpg", FileMode.Open); 
        } 
        // initialise the binary reader from file streamobject 
        br = new BinaryReader(fs); 
        // define the byte array of filelength 
        byte[] imgbyte = new byte[fs.Length + 1]; 
        // read the bytes from the binary reader 
        imgbyte = br.ReadBytes(Convert.ToInt32((fs.Length))); 
        drow(0) = imgbyte; 
        // add the image in bytearray 
        dt.Rows.Add(drow); 

Monday, October 27, 2014 6:41 AM

Thank you for reply

I write code above

 but picture not show in crystal report why

ARE any thing remaining to add 

please help me if possible

 


Monday, October 27, 2014 9:03 AM

Hello,

I do not have the environment currently so I'm not able to reproduce this issue, but I would recommend you consult SAP Crystal Report forum about this issue, they may still have the environment.

I've also saw a related thread which might be helpful, you can check it from this link:

http://scn.sap.com/thread/1753348

Regards,

Barry
We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
Click HERE to participate the survey.


Monday, October 27, 2014 9:33 AM

Thank you for reply

I write code above

 but picture not show in crystal report why

ARE any thing remaining to add 

please help me if possible

 

If you set up the datatable like that, put a break point in at the top of the method and use f10 to step through and explore what happened. Does it definitely get the file?

You also need to have built the report against a set of data matching what you give it ( as I explained above ).

This code here is out an old web project of mine, it grabs a datatable out of session, renames it and presents it to the report using SetDataSource

        ReportDocument rd;
        DataTable dt = (DataTable)Session["BlaaData"];
       //   make the name of the datatable match what the report expects
        dt.TableName = "DataTable1";
        rd = new ReportDocument();
        rd.Load(Server.MapPath("Reports\\blaaa.rpt"));
        rd.SetDataSource(dt);

        rd.Refresh();
        CrystalReportViewer1.ReportSource = rd;

        CrystalReportViewer1.RefreshReport();
        CrystalReportViewer1.DisplayGroupTree = false;

Monday, October 27, 2014 10:36 AM

Thank you for reply

I changed my code i create

Dataset1

DataTable1 inside Dataset1 have these fields

DriverID

DriverName

EmplyeeName

ResidentNo

and make stored procedure as 

create proc  ViewEmployeeNoR
(
@EmployeeNo   nvarchar(20)

)
as
select * from dbo.ViewTest6 where DriverID=@EmployeeNo

and make Dataset1 as datasource of my report CrystalReportData1

and put in form crystal report viewer and textbox1 and button1

under button1 i write this code 

SqlConnection con = new SqlConnection("data source=192.168.1.5; initial catalog=hrdata;uid=sa; password=1234");
 SqlCommand cmd = new SqlCommand();
 cmd.Connection = con;
 cmd.CommandType = CommandType.StoredProcedure;
            //cmd.CommandText = "Select DriverID,DriverName,EmplyeeName,ResidentNo from Employee where DriverID=@EmployeeNo";
 cmd.CommandText = "ViewEmployeeNoR";
 cmd.Parameters.Add("@EmployeeNo", SqlDbType.NVarChar, 20);
 cmd.Parameters["@EmployeeNo"].Value = textBox1.Text;
 SqlDataAdapter da = new SqlDataAdapter();
 da.SelectCommand = cmd;
 DataSet1 ds = new DataSet1();
 da.Fill(ds, "DataTable1");
 Reports.CrystalReportData1 objRpt = new Reports.CrystalReportData1();
 objRpt.SetDataSource(ds.Tables[0]);
 crystalReportViewer1.ReportSource = objRpt;
 crystalReportViewer1.Refresh();

but i dont know how to customize this code to accept adding image

this all what i do

can any one help me how to add image in crystal report from local path


Monday, October 27, 2014 10:57 AM

You need to add a column which will present the picture.

In the link I supplied above he does:

dt.Columns.Add("Image", System.Type.GetType("System.Byte[]")); 

Where dt is his datatable, that's adding the column.

Remember though.

You need to build your report against something and that means you will need a dummy table which has a blob column representing your image, as well as your other columns.

.

Have you considered using the current free version of sap crystal reports from the link I provided above?

I'm not sure it will work in vs2008 and have no way to tell but it would be somewhat simpler.

Why are you still using vs2008 anyhow?

It's long obsolete.


Monday, October 27, 2014 11:37 AM

Can you explain for me by details

i have problem in how to show image 

i make the code below(as you tell me) but image not show if possible help me

under the button i write

Result: report show data without image why

 the following my code

SqlConnection con = new SqlConnection("data source=192.168.1.5; initial catalog=hrdata;uid=sa; password=1234");
 SqlCommand cmd = new SqlCommand();
 cmd.Connection = con;
 cmd.CommandType = CommandType.StoredProcedure;
            //cmd.CommandText = "Select DriverID,DriverName,EmplyeeName,ResidentNo from Employee where DriverID=@EmployeeNo";
 cmd.CommandText = "ViewEmployeeNoR";
 cmd.Parameters.Add("@EmployeeNo", SqlDbType.NVarChar, 20);
 cmd.Parameters["@EmployeeNo"].Value = textBox1.Text;
 SqlDataAdapter da = new SqlDataAdapter();
 da.SelectCommand = cmd;
 DataSet1 ds = new DataSet1();
 da.Fill(ds, "DataTable1");
 DataTable dt = new DataTable();
 DataRow drow;
 dt.Columns.Add("Image", System.Type.GetType("System.Byte[]"));
 drow = dt.NewRow();
 string path = Path.Combine("\\192.168.1.5\Personal Pictures", textBox1.Text) + ".jpg";
 if (File.Exists(path))
 {
 fs = new FileStream("\\192.168.1.5\Personal Pictures\" + textBox1.Text + ".jpg", FileMode.Open);
 }
 else
 {
                    
 MessageBox.Show("Please File Not Exist");
                  
 }
               
 br = new BinaryReader(fs);
 byte[] imgbyte = new byte[fs.Length + 1];
 imgbyte = br.ReadBytes(Convert.ToInt32((fs.Length)));
 drow[0] = imgbyte;
 dt.Rows.Add(drow);
 br.Close();
 fs.Close(); 
 Reports.CrystalReportData1 objRpt = new Reports.CrystalReportData1();
 objRpt.SetDataSource(ds.Tables[0]);
 crystalReportViewer1.ReportSource = objRpt;
 crystalReportViewer1.Refresh();


Monday, October 27, 2014 12:46 PM

This bit of code here:

 DataSet1 ds = new DataSet1();
  da.Fill(ds, "DataTable1");       // you make a datatable here, use it
  DataTable dt = new DataTable();  // remove
  DataRow drow;
  dt.Columns.Add("Image", System.Type.GetType("System.Byte[]"));
  drow = dt.NewRow();

Don't use dataset, use datatable.

You can do:

        SqlDataAdapter da = new SqlDataAdapter(sqlstring, DB.connString);
        dt = new DataTable();
        da.Fill(dt);

Or you can get the datatable out the dataset.

DataTable dt = ds.Tables[0];

You fill your dataset which makes a datatable in it, then you don't use that datatable.

When you fill a datatable you're getting the data and reading it into the datatable, which creates rows.

You need to update those rows you have there with your image data rather than adding a new row.

Something like

foreach (datarow dr in dt)
{
    dr["Image"] = imgbyte ;
}

Monday, October 27, 2014 1:20 PM

Im confused can you more explain

can you write true code all one piece

meaning all code


Monday, October 27, 2014 2:01 PM

my code after you tell me is 

                                                     

SqlConnection con = new SqlConnection("data source=192.168.1.5; initial catalog=hrdata;uid=sa; password=1234");
 SqlCommand cmd = new SqlCommand();
 cmd.Connection = con;
 cmd.CommandType = CommandType.StoredProcedure;
            //cmd.CommandText = "Select DriverID,DriverName,EmplyeeName,ResidentNo from Employee where DriverID=@EmployeeNo";
 cmd.CommandText = "ViewEmployeeNoR";
 cmd.Parameters.Add("@EmployeeNo", SqlDbType.NVarChar, 20);
 cmd.Parameters["@EmployeeNo"].Value = textBox1.Text;
 SqlDataAdapter da = new SqlDataAdapter();
 da.SelectCommand = cmd;
 DataSet1 ds = new DataSet1();
 da.Fill(ds, "DataTable1");
 DataTable dt = ds.Tables[0];
 DataRow drow;
 dt.Columns.Add("Image", System.Type.GetType("System.Byte[]"));
 drow = dt.NewRow();
 string path = Path.Combine("\\192.168.1.5\Personal Pictures", textBox1.Text) + ".jpg";
 if (File.Exists(path))
 {
 fs = new FileStream("\\192.168.1.5\Personal Pictures\" + textBox1.Text + ".jpg", FileMode.Open);
 }
 else
 {

 MessageBox.Show("Please File Not Exist");

 }

 br = new BinaryReader(fs);
 byte[] imgbyte = new byte[fs.Length + 1];
 imgbyte = br.ReadBytes(Convert.ToInt32((fs.Length)));
 drow[0] = imgbyte;
 dt.Rows.Add(drow);
 br.Close();
 fs.Close(); 
 Reports.CrystalReportData1 objRpt = new Reports.CrystalReportData1();
 objRpt.SetDataSource(ds.Tables[0]);
 crystalReportViewer1.ReportSource = objRpt;
 crystalReportViewer1.Refresh();

CAN you tell me how to add foreach to the codeand are modification done as you tell me


Monday, October 27, 2014 2:27 PM

More like this:

            DataTable dt = new DataTable();
            string connString = "data source=192.168.1.5; initial catalog=hrdata;uid=sa; password=1234";
            using (SqlConnection con = new SqlConnection(connString))
            {
                con.Open();
                SqlCommand cmd = new SqlCommand("ViewEmployeeNoR", con);
                cmd.CommandType = CommandType.StoredProcedure;    // Viewxxx doesn't seem a good name for a sp
                cmd.Parameters.Add("@EmployeeNo", SqlDbType.NVarChar, 20);
                cmd.Parameters["@EmployeeNo"].Value = textBox1.Text;
                SqlDataAdapter da = new SqlDataAdapter();
                da.SelectCommand = cmd;
                da.Fill(dt);
            }
            dt.Columns.Add("Image", System.Type.GetType("System.Byte[]"));

            string path = Path.Combine("\\\\192.168.1.5\\Personal Pictures", textBox1.Text) + ".jpg";
            FileStream fs;
            if (File.Exists(path))
            {
               fs = new FileStream("\\\\192.168.1.5\\Personal Pictures\\" + textBox1.Text + ".jpg", FileMode.Open);
            }
            else
            {

                MessageBox.Show("Please File Not Exist");

            }

            BinaryReader br = new BinaryReader(fs);
            byte[] imgbyte = new byte[fs.Length + 1];
            imgbyte = br.ReadBytes(Convert.ToInt32((fs.Length)));

            foreach (DataRow dr  in dt.Rows)
            {
                dr["Image"] = imgbyte;
            }
            ReportDocument objRpt = new Reports.CrystalReportData1();
            objRpt.SetDataSource(dt);
            crystalReportViewer1.ReportSource = objRpt;
            crystalReportViewer1.Refresh();

I'd have to create my own crystal report to test this, so whilst I compiles I've done zero testing.


Monday, October 27, 2014 3:39 PM

Thank you for help

it give me error unassigned local variable fs

i make only filestream fs=null

and after this program run and get all data successfully but

Image not come why i dont know

the path found above

\\192.168.1.5\Personal Pictures i using more times in program and get pictures

so that i dont know what the proplem or what remaining

if you know help me

I try to add image field to datatable with syste.byte[] but also not work

why


Monday, October 27, 2014 4:10 PM

You need to get used to debugging and stepping through your code.

Add a break point, f10 to step through.

Watch what happens.

Fix it.

.

I didn't give any great thought to that part of your code, I was too busy refactoring all the other bits.

But....

You can do:

byte[] bytes = File.ReadAllBytes(@"c:\folder\myfile.ext");

Which means you can do something more like:

            DataTable dt = new DataTable();
            string connString = "data source=192.168.1.5; initial catalog=hrdata;uid=sa; password=1234";
            using (SqlConnection con = new SqlConnection(connString))
            {
                con.Open();
                SqlCommand cmd = new SqlCommand("ViewEmployeeNoR", con);
                cmd.CommandType = CommandType.StoredProcedure;    // Viewxxx doesn't seem a good name for a sp
                cmd.Parameters.Add("@EmployeeNo", SqlDbType.NVarChar, 20);
                cmd.Parameters["@EmployeeNo"].Value = textBox1.Text;
                SqlDataAdapter da = new SqlDataAdapter();
                da.SelectCommand = cmd;
                da.Fill(dt);
            }
            dt.Columns.Add("Image", System.Type.GetType("System.Byte[]"));

            byte[] imgbyte;
            string path = string.Format(@"192.168.1.5\\Personal Pictures\\{0}.jpg",  textBox1.Text);
            if (File.Exists(path))
            {
               imgbyte = File.ReadAllBytes(path);
            }
            else
            {
                MessageBox.Show("Please File Not Exist");
            }

            foreach (DataRow dr  in dt.Rows)
            {
                dr["Image"] = imgbyte;
            }
            ReportDocument objRpt = new Reports.CrystalReportData1();
            objRpt.SetDataSource(dt);
            crystalReportViewer1.ReportSource = objRpt;
            crystalReportViewer1.Refresh();

Tuesday, October 28, 2014 7:54 AM

Thank you for reply

it work finally

but if possible i need answer to these questions

1-if i create more data set and inside it datatable1 how the code can know which datable

related to which data set meaning it is prefer to use data set

2- why the code accept to add image manually and not accept adding image from c#

if possible please answer fro these questions after this i can close the post