Personnel card creation

our company wants to print a personal map for our staff, so we have prepared a template that contains a place for each person, a photo, a name and a department.
we have a database table that includes the path to the photo, name and department of each person.
I would like to know if there is an option to go through this table and add person data to the card template and save it.
I am using C # .Net, but if you know a better solution for this reason, I would be happy to hear.

preview of card template

0


source to share


2 answers


This is not a problem at all using C # and GDI +

Here's a short version:

  • Create the Bitmap

    desired size and resolution
  • Measure the coordinates of images and text you want on it
  • Fetch data from your database
  • Use Graphics.DrawImage

    and Graphics.DrawString

    to create graphics
  • Save in the format you like, preferably PNG

    as this will keep the text legible

Here are the details:

  • You need to calculate how many pixels your image should have. Since you want to be able to print it, you must use at least 150 dpi or 200 dpi.

The image you posted has no DPI settings and 1004x638 pixels; setting it to 150dpi, the physical size is 170x108 mm. Let's assume it's ok ..

So, we create a bitmap with these parameters:

Size keyCardSize = new Size (1004, 63);
float Dpi = 150f;
Bitmap bmp = new Bitmap(keyCardSize.Width, keyCardSize.Height);
bmp.SetResolution(Dpi, Dpi);

      

  1. The code below uses millimeters. You can change this to something else.

In your template we see 6 images (logo, photo and 4 icons) and 7 pieces of text (name, title, department and four contact texts).

The basic commands for drawing an image or text using Graphics G

are as follows:

   G.DrawImage(bitmap, location);
   G.DrawString(text, font, brush, location);

      

In our case, this works great for the logo and photography as they are aligned to the left. All you have to do is measure positions and create location points. Make sure to either create images with the correct size and resolution, or that you adjust for dpi to compensate for different pixel sizes!



Update: I have included the code to adapt the photo dpi

to make the frame width 30mm in the template. This assumes that the proportions are correct and / or that we care more about width than height. If we need to match both, either get the correct proportions or ask for the cropping code; -)

Measuring the rest of our items is a little trickier as they are all right-aligned. Here's an example of how to do this for the txt1 line:

SizeF s1 = G.MeasureString(txt1, font1, PointF.Empty, StringFormat.GenericTypographic);
G.DrawString(txt1, font1, brush1, new Point((int)(rightBorder - s1.Width), y1));

      

You can (and should) measure the top ( Y

) of each location, but the left ( X

) must be calculated as above!

Note that you need to tell the measurement team the font you want to use; ignore other parameters! After measuring the right border, these commands will work well with the required data and graphics.

  1. Pulling data from your database. I suppose you can do it! I also assume that you can modify and extend the code below to fill in the data fields and make it filename

    dynamic with your records.

4 & 5. An example of this code:


 private void Button_Click(object sender, EventArgs e)
 {
    string FontFamily = "Verdana";

    string fileName = "d:\\template.png";

    Size keyCardSize = new Size (1004, 638); // 170x108mm
    float Dpi = 150f;
    Bitmap bmp = new Bitmap(keyCardSize.Width, keyCardSize.Height);
    bmp.SetResolution(Dpi, Dpi);

    // test data:
    Bitmap photo = new Bitmap(@"D:\scrape\sousers\SOU_JonSkeet.jpeg");
    // I have measured the photo should be 30mm wide
    // so with 25.4mm to the inch we calculate a fitting dpi for it:  
    float photoDpi = photo.Width * 25.4f / 30f;
    photo.SetResolution(photoDpi , photoDpi );

    Font font1 = new Font(FontFamily, 23f);
    Font font2 = new Font(FontFamily, 12f);
    Font font3 = new Font(FontFamily, 14f);

    using (Graphics G = Graphics.FromImage(bmp))
    using (SolidBrush brush1 = new SolidBrush(Color.MediumVioletRed))
    using (SolidBrush brush2 = new SolidBrush(Color.Gray))
    {
        G.Clear(Color.White);
        G.InterpolationMode = InterpolationMode.HighQualityBicubic;
        G.PageUnit = GraphicsUnit.Millimeter;
        G.SmoothingMode = SmoothingMode.HighQuality;

        StringFormat sf = StringFormat.GenericTypographic;

        int lBorder= 10;
        int rBorder= 160;
        int y1 = 10;
        int y2 = 25;
        //..
        int y4 = 60;
        //..
        //G.DrawImage(logo, imgLoc1);
        G.DrawImage(photo, new Point(lBorder, y4));
        //G.DrawImage(img3, imgLoc3);
        //G.DrawImage(img4, imgLoc4);
        //G.DrawImage(img5, imgLoc5);


       // test data:
        string txt1 = "Jon Skeet";
        string txt2 = "C Sharp Evangelist";
        //..

        SizeF s1 = G.MeasureString(txt1, font1, PointF.Empty, sf);
        SizeF s2 = G.MeasureString(txt2, font2, PointF.Empty, sf);
        //..

        G.DrawString(txt1, font1, brush1, new Point((int)(rBorder- s1.Width), y1));
        G.DrawString(txt2, font2, brush2, new Point((int)(rBorder- s2.Width), y2));

        //G.DrawString(txt3, font2, brush2, txtLoc3);
        //..
        //G.DrawString(txt7, font3, brush2, txtLoc7);

        G.FillRectangle(brush1, new RectangleF(rBorder - 1.5f, 52f, 1.5f, 46f));

  }

  bmp.Save(fileName, ImageFormat.Png);

  font1.Dispose();
  font2.Dispose();
  font3.Dispose();

  photo.Dispose();
  //..
}

      

Hope this helps you. If you have any questions, do not hesitate to ask.

Here's a rudimentary result:

enter image description here

Riddle: you can simplify all the code by using a template as a start: you can have the logo, icons and vertical bar in place, and you only need to draw one image and texts ..!

+4


source


Okay, just the idea might not work, but I thought I was throwing something out to help!

How about creating a program that, as you say, loops the database. But for State Maps, a GraphicsBox-like user interface and a few text fields are created; Create / use a print function to Ui, make a borderless window for printing.



I'm not sure if this will work as I am using C ++ and never thought of doing something like this, but I got it off the top of my head to get it back, you never know!

But then you will obviously be printing on high quality plastic I suppose, or does it get laminated? Not that really interesting, just interesting :)

0


source







All Articles