I want to make very simplistic paint/image editor. Mainly, for pixel editing, but that doesn't seem relevant.
To ease up my effort, I decided to keep the image size at 16x16.
I populate the form, add a PixelBox and slap a default image on it.
Of course, I need to make the pixels visible, set the interpolation to NearestNeighbor.
Then, I stretch the pixelbox to 320x320. And there the situation arises.
The image is displayed as thus:
Cropped image
Could someone shed some light on this? This is just a 16x16 image with a checkerboard pattern that I made, but I can't figure out why it is displayed with that offset at the top left.
Also, no code as been yet added. I assume this is default behavior?
If you look at the examples on the page that exact same error happens, so it must be a bug on the PixelBox.
Instead of using a custom control for this type of operation just use the standard PictureBox and scale the image by yourself:
public Bitmap ScaleBitmap(Bitmap src, Size NewSize)
{
Bitmap bmp = new Bitmap(NewSize.Width, NewSize.Height, src.PixelFormat);
Graphics g = Graphics.FromImage(src);
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
g.DrawImage(src, new Rectangle(Point.Empty, NewSize), new Rectangle(0, 0, src.Width, src.Height), GraphicsUnit.Pixel);
g.Dispose();
return bmp;
}
Related
Hello Stackoverflow Community.
I currently work on an application which has a cursor region magnifyer feature, for the user to pick a color.
However, i've the problem that the Picturebox has white edges on the right and bottom, even though the image captured is only one dark color.
The captured screen is 10x10 pixel and the Picturebox is 80x80 pixel and it's SizeMode set to StretchImage.
I checked if the raw captured image maybe contains this edges already by saving it and checking it in Photoshop. But the raw captured image is fine, so it must be something weird with the Picturebox.
Here you can see how it looks (The mousecursor and the capture-region[green rectangle] are just painted on the screenshot for demonstration, as i was not able to screen my cursor, and yes - the green region is painted way too large, it should be just 10x10 pixel ^^)
Has it maybe something to do with the way the Image get's stretched internally? If so, is there any, not too complicated way around it?
I appreciate any help in advance :)
//Edit: I think it's actually about the stretching
I found this topic Image after resize has white border but i don't know what the GetSize() Method is, or where it is (from)
Have a great day!
I found a solution for the edges here, as you can see in the first screen. However, in the second screen you can see a 2x2 pixel capture, stretched to 80x80 pixel with the found "solution", will mix colors as it's actually 80x80 pixel in the end, while i want to have it displaying the raw pixels, so, 3 black ones and one white one in this case. Now i am even more stuck ^^
I guess i should instead read the pixel colors of the single pixels from captured image and set the colors in the preview picturebox, or make 4 panels in the case of just 2x2 pixels
public new Image Resize(Image image, int targetWidth, int targetHeight)
{
var resizedImage = new Bitmap(targetWidth, targetHeight);
using (var graphics = Graphics.FromImage(resizedImage))
{
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
var attributes = new ImageAttributes();
attributes.SetWrapMode(WrapMode.TileFlipXY);
var destination = new Rectangle(0, 0, targetWidth, targetHeight);
graphics.DrawImage(image, destination, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);
}
return resizedImage;
}
//Edit:
Okay i think i'm gonna use Get/SetPixel or Panels(for small captures), as i did here on the right, the left is still the 80x80 Picturebox
Sometimes when I resize semi-transparent png's I get weird white pixels on shapes edges. This happens only with images that have shapes (not photos) and when InterpolationMode is set to HighQualityBicubic. Does anyone know why this white pixels show? I get them only on some images.
This is the result I get:
This is the source file:
This is similar file, that does not cause that "white pixel" effect.
Drawing code is very simple:
Bitmap resize = new Bitmap(1024, 177, PixelFormat.Format32bppArgb);
using (Graphics g = Graphics.FromImage(resize))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(Properties.Resources.Wave01, 0, 0, 1024, 177);
}
Please note, that I use HighQualityBicubic because the code is used for resizing various types of images including photos. Using InterpolationMode.Default seems to solve the problem, but then resizing some image types may produce worse results than HighQualityBicubic.
suppose i have two images img1.jpg and img2.jpg. using some routine i could extract the difference between two images. now difference is saved in another bitmap variable called diff
here is code
Bitmap diff = new Bitmap(bounds.Width, bounds.Height);
Graphics g = Graphics.FromImage(diff);
g.DrawImage(secondImg, 0, 0, bounds, GraphicsUnit.Pixel);
g.Dispose();
i know the difference in terms of rectangle and also save the difference in diff variable. now i want to merge or draw this difference on my first image. i tried with code like
Graphics g1 = Graphics.FromImage(firstImg);
g1.DrawImage(secondImg, 0, 0, bounds, GraphicsUnit.Pixel);
g1.Dispose();
but it is not working because when i open my first image img1.jpg then i am seeing any changes in that image. i want to draw the changes on my first image img1.jpg. what is wrong in my code which is not being able to dump or draw the changes on first image.
basically i have to reconstruct img1, if i have img2 and difference between img2 and img1.
please guide me. thanks
I'm rendering an image into a System.Drawing.Bitmap and subsequently drawing it into a window, however I can see that the edges are being anti-aliased. How do prevent this?
Some more detail. The bitmap is created like thus:
new Bitmap (this.Width, this.Height, Imaging.PixelFormat.Format32bppArgb)
I then set pixels to either Color.Black or Color.White. I've tried using both Bitmap.SetPixel and writing bytes directly to the bitmap data using Bitmap.LockBits.
Once the bitmap is ready I draw it in my Form.OnPaint override:
pea.Graphics.DrawImage
( !this.bitmap
, this.ClientRectangle
, new Rectangle (0, 0, this.Width, this.Height)
, GraphicsUnit.Pixel
)
Every pixel should either black or white however I can see that pixels at the edges are grey.
Set the InterpolationMode property to NearestNeighbor and PixelOffsetMode to None.
pea.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
pea.Graphics.PixelOffsetMode = PixelOffsetMode.None; // or PixelOffsetMode.Half
Drawing the bitmap unscaled is best. In which case you probably want to use the ClientSize.Width and Height properties to initialize the bitmap. Odds are good that you are making the bitmap too large right now by including the form's border and caption. I can't tell from the snippet.
I have two overlapping pictureboxes.The images of both picture boxes have some transparent pixels.I want to see the bottom picture box through the transparent pixels of the overlapping picture box.
I tried setting the background color of both picture boxes as transparent.But it just sets the back color of the picture box to the background color of the form.
Clearly you are using Winforms. Yes, transparency is simulated by drawing the pixels of the Parent. Which is the form, you only see the form pixels, stacking effects don't work. There's a KB article that shows a workaround for this. It is painful. Another approach is to not use PictureBox controls but just draw the images in the form's Paint event.
Consider WPF, it has a very different rendering model that easily supports transparency.
Solutions to that problem might be various, and it mainly depends on your skills and amount of work will depend on kind of images you're dealing with. For example if images are always same resolution, size and overlapping image supports transparency you could try to do manipulation of two Image objects and draw one over another, then display it in PictureBox. Or if you will need to do it multiple times in various places of your app you could even consider creating your own UserContriol.
Code in answer of this question, method ResizeImagein particular, show how to create resized, good quality image, all you need it is to change it a little. Make it to get two Images as input parameters, and change it to draw one image over another.
Changes might look like this
public static Bitmap CombineAndResizeTwoImages(Image image1, Image image2, int width, int height)
{
//a holder for the result
Bitmap result = new Bitmap(width, height);
//use a graphics object to draw the resized image into the bitmap
using (Graphics graphics = Graphics.FromImage(result))
{
//set the resize quality modes to high quality
graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//draw the images into the target bitmap
graphics.DrawImage(image1, 0, 0, result.Width, result.Height);
graphics.DrawImage(image2, 0, 0, result.Width, result.Height);
}
//return the resulting bitmap
return result;
}
And use it, for example, like this:
pictureBox1.Image = CombineAndResizeTwoImages(Image.FromFile("c:\\a.png"), Image.FromFile("c:\\b.png"), 100,100);
But that its only example, and you must tune it up to your needs.
Good luck.
If it's one PictureBox inside another, you can use:
innerPictureBox.SendToBack();
innerPictureBox.Parent = outerPictureBox;