I have an image frame:
1 http://i48.tinypic.com/wugmc2.png
The image resolution is: 533x300
Using GDI+ I Re-size the image to 300x533:
Now as you can see it distorted the width/height of the border and shrunken Santa Claus...
Is there a way using GDI+ c# to prevent this distortion of the image frame?
Scaling the image will always result into a skewed santa. If that is not what you are looking for, try creating separate images of your santa and the border.
If the border will stay that simple as a red line, I am almost sure that there is a simple control for just drawing red borders in GDI. If you are going to create some christmas border with branches and trees, you need a bit more smaller images to separate this problem.
Create a separate santa to use as an overlay
Create separate images for the corners
Create separate tillable images for vertical and horizontal borders
Then place the images by yourself and tile the images in the centers like so:
I have never worked with GDI, but this is a general solution for scaling borders.
Related
I have a WriteableBitmap object which I load a .jpg image into and show it in an image control. Now I would like to be able to let the user draw on that image with a little half-transparent brush.
Right now I am handling the MouseDown and MouseMove events to draw a little half-transparent circle on every change of the mouse's coordinates over the image:
MyWriteableBitmap.FillEllipseCentered(x, y, 1, 1, myColor);
That clearly does not refresh fast enough though - leaving me with a set of dots (unless the user moves the mouse very very slow).
My temporary solution is to just draw lines from one point to another and update the two points on every MouseMove event - the curve is consistent that way but is only one-pixel wide, which doesn't look great.
What is the best approach for me to tackle that problem?
You'll get better performance and automatic conversion to splines (if you want it) by using an InkCanvas instead:
<InkCanvas>
<InkCanvas.DefaultDrawingAttributes>
<DrawingAttributes Color="Blue" Width="8" Height="8" FitToCurve="True" />
</InkCanvas.DefaultDrawingAttributes>
</InkCanvas>
You can always get it to render itself into a bitmap later if you need it:
RenderTargetBitmap bitmap = new RenderTargetBitmap((int)theCanvas.ActualWidth, (int)theCanvas.ActualHeight, 96d, 96d, PixelFormats.Default);
bitmap.Render(theCanvas);
UPDATE: this works for transparent brushes as well BTW, and also pressure-sensitive pens (if enabled). The main problem is that the performance will drop as the user draws more and more lines, but you can easily fix that by rendering to a bitmap and then setting that bitmap to be the InkCanvas background i.e. the InkCanvas shouldn't never be displaying more than 1 spline, and only when the user is drawing it.
I am drawing lines on a background image in a c# panel. The panel is anchored to the form so as the form resizes the panel resizes. The background image is set to be stretched so all you see as you resize the form is the background image.
My initial problem:
The lines drawn on the panel (via the OnPaint event) stay where they were originally drawn as the image resizes.
My current solution:
Record the location of the line and redraw it on a new bitmap by scaling the X and Y coordinates (works fine).
My new problem:
As you continually resize the window and draw lines you can't calculate the scaling factor from any point in time and apply it to all lines since the lines were originall drawn in different size images.
The two options I think I have:
After I redraw the line go through my array of lines and update the coordinate information so it now matches the current scale.
Or
In addition to storing the coordinate information of the line also store the size information of the panel at the time it was drawn so I can always calculate the scale for each line based on when it was drawn and the new panel size.
What I'm hoping for:
If you have thoughts on either of the two approaches that would be greatly appreciated....Even better would be to point me in the direction of a far better method to do this (I am fairly new to graphics processing in c#).
Can't write a comment, much as I want to. You do have a few options:
Draw your lines directly on the original Bitmap. This might not be an option for you, depending on the task.
Do it as you're doing now, keeping track of the lines' coordinates, updating them on resize, and redrawing them on Paint - if you use this, you'll be able to move and delete them, too,
Or do it by introducing a "scale factor" (float) which you update on every resize, and in your Paint event handler you draw everything using that scale factor. As you create a line, you calculate its coordinates using the scale factor BACK TO an unified coordinate system (scale factor 1) and then you don't have to modify your coordinates at all. This might be easy to debug due to that unified coordinate system. This is what I'd recommend, but it again depends on your task.
Draw to a full transparent Bitmap of the same size as your original image, use a scale factor like in the previous option. On creating a line, calculate its coordinates in the unified coordinate system, draw it on the Bitmap, and then on every Paint, draw the entire Bitmap over your original one. This, again, might not be an option if you need to delete or move your lines, or if you're tight on memory, or you don't want your lines to be blurred when you scale up, but somehow many ppl like this because it's like a "layer in Photoshop". :)
I would like to be able to add an image to a live tile so that there is no stretching and the image looks normal. I am getting my images from the PhotoChooserTask, which contain images from the medialibrary. As of now I can successfully place an image on a live tile, but it is stretched and the aspect ratio is not correct. How would I be able to find the aspect ratio of the image and crop the image so that it ends up being a square with dimensions 173x173 with no streching? I have followed a couple tutorials found online but nothing seems to accomplish this the way I need it to.
I accomplished this by referencing Resize image for Live Tile - WriteableBitmapEx which proved to have the correct implementation.
before question think about for example photoshop. When you draw a rectangle on the picture.You can move it. And when you move it works very quickly and it doeasnt make some traces on the picture.
So my question is, how to do that in c# application?
This might be useful for you
Image Processing for Dummies with C# and GDI+ Part 1 - Per Pixel Filters
Image Processing for Dummies with C# and GDI+ Part 2 - Convolution Filters
Image Processing for Dummies with C# and GDI+ Part 3 - Edge Detection Filters
Image Processing for Dummies with C# and GDI+ Part 4 - Bilinear Filters and Resizing
Image Processing for Dummies with C# and GDI+ Part 5 - Displacement filters, including swirl
Image Processing for Dummies with C# and GDI+ Part 6 - The HSL color space
When you are moving the rectangle, Photoshop doesn't put it in the image and then draw the image, instead the image is drawn without the rectangle, and the rectangle is drawn on top of that on the screen. That way when you move the rectangle it can redraw the part of the image that previously was covered by the rectangle, and draw the rectangle at the new position.
I think you're asking about selection rectangles (or other temporary shapes) on top of the document image. This effect is sometimes known as “rubber banding”, especially when drawing a line from one point to another (it stretches like a rubber band).
Traditionally, this was done by using XOR drawing -- instead of overwriting the image with the selection shape, the colors in that area are inverted. Then, to remove the selection, it suffices to invert the colors again, returning to the same original image. Today, graphics rendering is fast enough that such tricks are not usually necessary; it suffices to simply repaint that part of the window (without the rectangle).
Either way, it is important to recognize that the document image — the image the user is editing — is not the same as the window image, which is just a copy to be remade whenever necessary. In the window, the document image is drawn and then selections, guide marks, and other such controls are drawn on top of it.
I'm not familiar with C#'s GUI facilities (and I understand there is more than one GUI framework you might be using), but it's probably got the usual structure of putting many "widgets", "views", or "controls" in the window (possibly nested inside each other). You can do a straightforward selection box — though not an optimally efficient one — by just putting an appropriately sized rectangle widget (with a solid border and a transparent background) on top of an image widget. This lets your GUI framework take care of the appropriate redrawing for you and is probably a good cheap way to start.
With a mobile device I take a picture of a flat light object on a dark surface. (for instance a coupon clipped out of a newspaper).
The image is then run through a brightness/contrast filter. If it is too dark, vital components are left out. If it is too bright, the writing on the coupon is lost.
This image is then converted into a bitonal image. Any pixel that is 50% or more dark is converted to black, everything else is white. (done)
I am left with a skewed bitonal image (think of a white trapezoid inside a larger rectangle with a black background).
I need to figure out how to crop the image - which when it's on a black background is easier than when it's on a white background. Then, I have to de-skew the image so it is rectangular instead of trapezoidal, while attempting to preserve aspect.
The end result should be a nicely cropped, bitonal, readable image of the coupon.
To crop your image, you can use the LockBits method and scan through all your pixels to find the first pixel with content from the top, left, right and bottom, respectively. How to use LockBits is described nicely here: https://web.archive.org/web/20141229164101/http://bobpowell.net/lockingbits.aspx
Assuming your image is not rotated, and that the skewing comes from the camera held at an angle against the table where the coupon is being photographed, you should now have a skewed image of the coupon, fitting perfectly within the bounds of the cropped bitmap. You should also know the four corners of the trapezoid.
"Undistorting" an image is not as easy as you might think though. However, good people have solved this problem and you can probably port their code to your own use. Here is a link I used to explore this problem in a similar case some time ago:
http://ryoushin.com/cmerighi/en-US/2007-10-29_61/Image_Distortion_Enhancements
I also have some code stored somewhere if you can't make any sense of what you find.