0

Hello I'm working on a WPF program to automate the process of producing cards (I feed it information from a database, it spits out image files of the correct dimensions).

These cards are made up of 3 effective "layers" placed on top of each other and should produce an output like so

enter image description here

(if I need to remove it I will, since I just grabbed an image with the right aspect ratio).

Now I can get the separate "layers" as their own bitmaps with something like

//Get the filepath and store it in a variable named 'FilePath' before this
BitmapImage image =  new BitmapImage();
image.UriSource = (Uri)FilePath;

(I know that code isn't right but you get the idea).

So the question is, how do I add these three bitmaps together into a single bitmap that can then be saved as say a .png or such.

I know WinForms has a lot more options built in for image and bitmap manipulation but I am doing this in WPF.

I was thinking of doing this with byte arrays and using loops to copy values from one to the other but any better suggestions are highly appreciated.

NeoEyes
  • 19
  • 9
  • Why not use the WinForms implementation for image manipulation? Alternatively, for a pure WPF solution see Xavier's answer here: https://stackoverflow.com/questions/30991309/create-a-composite-bitmapimage-in-wpf – Klaus Gütter Dec 29 '18 at 06:28
  • Thankyou for that, I will look into this – NeoEyes Dec 29 '18 at 07:24

1 Answers1

0

I think it's important to understand here what WinForms and WPF actually are.

WPF did not "replace" all the stuff in WinForms. WinForms is essentially a wrapper to the underlying Windows GDI API, which is itself still very much a current technology and likely to remain so in the foreseeable future.

WPF replaces the rendering of GUI elements with an engine based on DirectX. In order to do this it has to provide its own image classes, but this is solely for the purpose of display within the hardware-accelerated DirectX environment.

This is an important distinction: WPF is not, in-and-of itself, a part of the Windows operating system. It uses DirectX for rendering, but DirectX itself is designed for interfacing to graphics hardware and not for direct image manipulation (with some rare exceptions like GPU processing). The GDI, however, is still very much a part of windows and was specifically designed for this kind of thing, all the way back to the days of software rendering.

So in other words, unless you have a very specific requirement that involves hardware accelerated display you may as well use the GDI. WPF and WinForms can co-exist alongside each other just fine because they do completely different things. Just because one of the things WinForms happens to do is expose an older rendering technology that you don't want to use yourself doesn't mean that WinForms as a whole is obsolete.

UPDATE: to use GDI functions you'll need to add a reference to System.Drawing; normally this is done for you when you create a windows project but if you've created a console application etc then you'll need to do it manually. The Graphics class provides many functions for rendering, but from what you've described this will probably cover most of what you're trying to do:

using System.Drawing;
using System.Drawing.Imaging;

namespace yournamespace
{
    class Program
    {
        private static void Main(string[] args)
        {
            // load an image
            var source = new Bitmap("source.png");

            // create a target image to draw into
            var target = new Bitmap(1000, 1000, PixelFormat.Format32bppRgb);

            // get a context
            using (var graphics = Graphics.FromImage(target))
            {
                // draw an image into it, scaled to a different size
                graphics.DrawImage(source, new Rectangle(250, 250, 500, 500));

                // draw primitives
                using (var pen = new Pen(Brushes.Blue, 10))
                    graphics.DrawEllipse(pen, 100, 100, 800, 800);
            }

            // save the target to a file
            target.Save("target.png", ImageFormat.Png);
        }
    }
}
Mark Feldman
  • 15,731
  • 3
  • 31
  • 58
  • 1
    Whilst I do appreciate the distinction you have provided (i genuinly didnt know the whole direct X thing) this politely has nothing to do with the question, all I am really asking is if there is a way to do this that doesn't involve a bunch of byte arrays or something similiar. I merely mentioned the fact I was doing this in WPF as context as it means I do not have access to some things something like WinForms does (and that is what most explanations for this type of question are for) – NeoEyes Dec 29 '18 at 07:23
  • Totally respect where you're coming from, but again you seem to think there's a "WPF" way of doing things. WPF uses ImageSource (and sometimes, more specifically, BitmapSource), which is a component of [WIC](https://learn.microsoft.com/en-us/windows/desktop/wic/-wic-about-windows-imaging-codec). All it is is just a standard API for decoding various image formats and representing them in a standardized way in memory so that the hardware vendors who create the graphics cards that WPF uses can convert that to their own internal native formats. – Mark Feldman Dec 29 '18 at 07:58
  • For my own personal edification I'm very curious as to what environment you could possibly be developing for that would support WPF and not GDI. I'm not aware of any such environment that exists, and it's the reason why WPF isn't available on Linux and never will be. – Mark Feldman Dec 29 '18 at 07:59
  • (BTW I apologize if I'm coming across as less-than-helpful, but one of the key purposes of this site is to provide answers that are of use to other people who stumble upon these pages in future. Others will most likely not have the same restrictions as you, so for them the correct answer is the one I provided i.e. "don't do this". More information about your specific limitations will help us answer your question more accurately whilst also helping visitors ascertain whether or not your specific restrictions match their own.) – Mark Feldman Dec 29 '18 at 08:19
  • I don't think a "WPF way of doing things" would be the right word for it. More of a "WPF way of accessing things" since different formats do have at least some difference in doing things which may take some accounting for. As for environment simple windows 10. On a fairly bog standard computer setup. So I probably do have access to GDI this is just the first I have heard of it so prior to this I didn't know what it was. – NeoEyes Dec 29 '18 at 10:45
  • So would I be able to ask you how would I use this GID? – NeoEyes Dec 29 '18 at 10:53
  • 1
    Ok now this is weird. I go to add the reference to system.drawing at the top of the file using System.Drawing;<\code> and it doesn't do anything still saying the bitmap doesn't exist but when I go into project references and check the box for it there suddenly the using directive turns the normal colour and it works. Odd but it's working now thankyou. – NeoEyes Dec 29 '18 at 22:44
  • Yep, that's normal. When I said "you'll need to add a reference to System.Drawing" project reference was what I was referring to. Glad to hear it's working, and good luck. – Mark Feldman Dec 29 '18 at 23:06
  • Thank's when I get it all up and running I will probably post an answer with the code i'm using in case it can be of assistance of others in future. – NeoEyes Dec 30 '18 at 01:06