System.Drawing.Region resizing - c#

I'm writing a paint application. User must be able to move with all objects after it's painted or edited. I have a brush and erase tool, so user can erase all or any part of object painted with brush. So I made an object DrawBrush that holds a System.Drawing.Region made from GraphicsPath.
But I don't know how to size it. I need to change size in every direction separately on mouse move (for example only to left)
can someone help me?
I'm able to do anything with this object (moving), but no sizing...

A region is like a fence - it simply marks out the boundary of an area. It does not "contain" any graphics, so resizing a region will have no direct/visible effect.
If you wish to be able to move or resize portions of a bitmap image within your editor, you will need to copy a piece of your main image (as specified by your region) into a temporary Bitmap. Then you can draw the tempoary bitmap back to your main image (in a different location and/or at a different size).
If you wish to be able to draw multiple objects in your painting program, and then edit them (move them around and resize them) independently later, then you will need to store each of them in a separate bitmap object and composite them together to display the final image on screen or save it to a flat bitmap format. If you don't keep all the shapes separately like this, you will lose too much information and you won't be able to edit them later.
Before you try to work out write the code to do this, you may need to think about the design of your editor - what does it need to do, and how will you achieve it? How is your "document" going to be described? (A single bitmap? many small bitmaps that are drawn at different locations? Vector paths?). If you write code before you understand how you will represent the document, you're likely to paint yourself into a corner (sorry about the pun) and get totally stuck.

Related

OpenCV C# - Detecting simple object in static image

I have no experience with images. I have to detect simple object in static image. For example I have image like:
I want to detect edges and remove background. Just to compare them.
Something like this.
Do u have any solutions of this problem? Images have often white backgrounds.
I've just thought about detect edges, and take everything what they contains.
To segment out the shoe-
Anadptive Threshold to remove the smooth changing background.
Sobelx, which removes the apparent background line, which i assume is
common for images of this setup.
dilate, closing operation to separate out the shoe.
Find contours, bounding box etc as per your choice.
Do an additional threshold if you want to remove the shadow at the bottom.

WPF - clone contents of container as geometry

Ok ive had a lot of bad luck using a visualbrush to try to print out pages from subsections of a large canvas. Works in general, but tends to rasterize some parts and creates bad output. (I've asked questions about this before).
So now I'm creating a bunch of copies of the canvas with all the same contents, and pinching down to invidual portions to print as a single page. This works, but obviously is slow and will only get slower with more pages.
So what might work well is, is there some way to do something similar toa visual brush, but to instead have it copy the contents from its "view" as a new geometry object of some kind? The contents of my canvas are a combination of lines, images, etc, so what would be nice is to be able to define the view of a brush and tell it to make an intersection copy of all the vector and raster objects visible into a new container of some kind.
This would allow me to use a single canvas, and take "snapshots" of the contents at different places to be used for printing the individual pages.
You could use RenderTargetBitmap to get a bitmap copy of the Canvas, and then crop the portion you wanted. If you specifically want a vector copy you'd need to write the canvas out to XPS.
Edit: If you want a vector copy, have you tried using XamlWriter.Save, edit the Xaml, and then XamlReader.Load?

Overlaying a 'dot' on to an image on click

I am trying to write a simple program that lets me overlay a dot on top of an image when the image is clicked. I can save the X and Y data back to my database but then I will want to be able to call that information back at a later date and overlay the dots again via code unlike the first time when the user had to click the image.
I got as far as capturing the X and Y of the click no problem but I am having trouble finding examples specifically for what I am trying to do. All of the examples online seem to be for saving the image with the added graphic but I do not need to do that as it will be the same image every time.
Once I can do this, I also need to work out a way that I can detect what area of the image has been clicked. The areas I need to mark out vary in shape and size so I need to try and work out a way to 'map' these areas and then cross reference with the co-ordinates of the users click (I assume that I may need to do some clever geometry stuff for that?)
If anyone has any suggestions of what subjects/classes/methods etc. to research for either of my queries, I would very grateful.
Thanks in advance
You can use the System.Drawing namespace to achieve this.
Create a control and override OnPaint and OnPaintBackground. Store your clicks in a List
In OnPaintBackground, draw the image using DrawImageUnscaled using the graphics object which is passed to you as a parameter.
In OnPaint, loop through your points array and call graphics.FillElipse or similar to draw a little dot.
Because this isnt a retained mode graphics system, you need to keep drawing these items so this may not suit a large number of dots. In that case, you can create an in memory bitmap and get a graphics drawing object using graphics.FromImage.

screen color filtering

I want to create a filter over a specific area of the screen to perform filtering opertions.
Examples what a filtering opertion might be:
    - inverting (e.g. change black pixel to white pixels, red to cyan)
    - masking pixels (e.g. mask = ff0000; input c79001 -> c70000)
    - operations like photoshop's layer effects
Here is an example of what it should look like:
http://img443.imageshack.us/img443/1462/overlayk.png
Does anyone know how to perform this under Windows OS.
(my prefered language is C#)
Thanks!
Depending on how fast you need the "filter" to update, a quick and hacky way is just to get a screenshot using CopyFromScreen while your filter window is invisible, apply the filter to the image data, and then set the filter window to display the image data.
If you want to do it without having to hide the window first, you'll probably need to do something like http://www.codeproject.com/KB/system/snapshot.aspx where you capture individual windows.
An even trickier but potentially faster thing to do, and requiring nearly complete use of p/invoke win32 calls, would be to not have a window at all, get the required capture windows based on their coordinates, capture the images as above, and then draw directly to the screen DC.
To clarify: you want an area of the desktop, not just within the bounds of your window, to be under your control allowing you to apply a per-pixel filter. If that's the case, I think what you need is DirectDraw using the XNA libraries. WPF MAY get you what you need, but WinForms will most likely not. There are third party tools as well.
If you want this capability only within the bounds of your application's window, for instance in a drawing application, it gets far easier. Every class in the Windows.Forms namespace that inherits from Control exposes a CreateGraphics() method. This method returns an object representing a drawing surface covering the screen area of the control, and is the basis for just about anything you want to do on a window involving custom graphics (and internally, it's used to draw the controls in the first place).
Once you have the Graphics object, you can draw Images on it. A popular method of drawing custom graphics like animations or games is to do the actual drawing on a Bitmap object (derived from the abstract Image) and then when you're done, draw the Bitmap on the Graphics area. This is done to reduce flicker; if the graphics area is shown to the user while it is being drawn on, the user will only see the complete image for a split second before it is "wiped" and redrawn, and shapes drawn halfway through will be there one moment and gone the next as they wait to be drawn. Drawing to a bitmap, then showing the Bitmap on the screen when you're done, means the user sees a complete image at a time.
You can extend this using transparency features to create multi-layered images. Have a Bitmap for every layer you wish to manipulate. Work on them seperately, then draw each of them, in their proper order from back to front, onto a master Bitmap, and draw that Bitmap on the screen. This allows you those PhotoShop-type manipulations where a part of the image is one layer, and can be manipulated independently of all others.
As for per-pixel filtering, Bitmap objects expose GetPixel() and SetPixel() methods, which allow you to grab the color of a single pixel, perform a filter calculation, and re-draw it. This process will be totally unaccelerated, and so limited by your CPU speed, but allow very fine control of your image, or repetitive tasks like your filters.

How do you draw a string to a Bitmap in Silverlight?

In normal C# it is easy to draw to a bitmap using the Grpahics.DrawString() method. Silverlight seems to have done away with Bitmap objects and Graphics is no longer available either. So...How am I meant to manipulate/create a bitmap when using Silverlight? If it helps, I am using Silverlight 3.
Let me tell you what I am doing. I am being given a template, basically a pre-rendered image. The user is then able to select from multiple images and enter the deisred text. I then render it to the image, adjusting size etc... within bounds and centering it in the pre-defined area of the image. If I can calculate the size (as in the MeasureString method) and then draw the string (as in the Graphics.DrawString method) that would be fine. The real question, no matter why I want to be able to do this, is can it be done?
The question is: why do you want to? Why not just use a TextBlock?
If you are trying to dynamically generate an image, use standard Silverlight/WPF controls (including TextBlock) and render them to a WritableBitmap.
Edit:
Ok, you've updated and expanded, which gives me more to go on. Unfortunately, you're not going to like the answer. First, keep in mind that Silverlight and WPF in general are vector based, and intended to be used as such. Although the Canvas allows you to do pseudo-pixel manipulations, you cannot be nearly as pixel-accurate as old-school GDI. This is a factor of your medium. If you absolutely have to measure things the way you want to measure them, I suggest you build your images on a remote server and transmit them to your Silverlight app.
You can calculate the size on-screen of the text rendered via a TextBlock using the ActualWidth and ActualHeight properties. But it only works on an already rendered control. Something like MeasureString is simply not available in Silverlight. Based on your description of your app, some user interaction could accomplish what you want. The user selects the image, enters the text, and is shown a preview. The user can then adjust the width and height of the various text areas until satisfied, at which point you can take a snapshot using the render method I liked to above.
The following may work, its a bit nebulous because I haven't tried yet myself.
The object you are looking for is the WritableBitmap.
You create a Visual tree, for example create your self a Grid or Canvas (you're not adding this to the UI). Add to it the selected image and a TextBlock positioned and sized as you prefer.
Create a new WritableBitmap either of a specific size or using the selected image to initialize it.
Use the WritableBitmap Render method passing the above root Grid or Canvas to it.
Now you have a bitmap which you should able to use to do whatever its you needed to do that required all this hoop jumping in the first place.

Categories