I am trying to get the location of touch from image on screen and map it to the correlating pixel from stream in order to determine the color (like a color picker).
But I realise the issue is the points gotten from the touch are mere small values which are just about matching the upper left corner of the actual image.
void OnTouchEffectAction(object sender, TouchActionEventArgs args)
{
// Get touchpoint location
Point pt = new Point();
pt.X = args.Location.X;
pt.Y = args.Location.Y;
GetColor();
}
I have simply called the GetPixel() function on the skbitmap image with x, and y from above location.
I have also tried resizing the image from stream to the canvasview but with no luck. please help?
I'm trying to combine two semi-transparent PNG images and display the result in a pictureBox1 which has its SizeMode property set to Zoom:
pictureBox1.Image = Image.FromFile(imgPath + "/myImg1.png");
If I directly display a single image, it is in the center and the existing borders are respected (as shown on the right side of example image below), but if I combines these two images - of the same size:
private void button2_Click(object sender, EventArgs e)
{
source1 = (Bitmap)Image.FromFile(imgPath + "/myImg1.png");
source2 = (Bitmap)Image.FromFile(imgPath + "/myImg2.png");
var target = new Bitmap(source1.Width, source1.Height, PixelFormat.Format32bppArgb);
var graphics = Graphics.FromImage(target);
graphics.CompositingMode = CompositingMode.SourceOver;
graphics.DrawImage(source1, 0, 0);
graphics.DrawImage(source2, 0, 0);
pictureBox1.Image = target;
}
the actual result shows the two images cropped and not centered (as shown on left side):
I'm trying to figure out how control the position and size of the two combined images, so they're drawn as shown in the image on the right.
The problem:
The OP is trying to center two images, of the same size in this case, inside a new Bitmap container. The size of the destination Bitmap is set to the size of one of the source images. The new Bitmap should be presented in a PictureBox. The control's SizeMode property is set to SizeMode.Zoom.
The unexpected result is shown in the image on the left, the expected result on the right:
What happens:
The destination Bitmap is sized as one of the source images, both of the same size.
The two source images are then drawn an Point(0, 0) in the new container.
It's expected - since the two semi-transparent images have the same size - that both will be drawn in the original position. The source images instead seem to be enlarged and moved towards the bottom-right corner of the new container.
It doesn't seem to be, this is exactly what happens.
The two source Images have a DPI descriptor set to ~72 DPI.
A standard PC screen has a resolution of at least 96 DPI.
When a new Bitmap is created as:
var newImage = new Bitmap(source1.Width, source1.Height, PixelFormat.Format32bppArgb);
the resolution of the new Bitmap is set to the screen resolution, hence at least 96 DPI.
An image loaded using this method:
var image = Image.FromFile([Image Path]);
is created using the original DPI descriptor and pixel format.
When a 72 DPI image is draw in a 96 DPI container, the different resolution is taken into consideration: the lower resolution image is enlarged.
As a result, the two 72 DPI images, draw inside a 96 DPI container of the same size, are not centered anymore, but it appears they're moved down and to the right (thus also clipped).
See also: Image is not drawn at the correct spot
How to solve:
When processing images of - quite possibly - different resolutions, pixel format and size, it's preferable to create a copy of the source images and work with new containers that have the same definition.
So, we can copy the source images to a standard 32Bit ARGB Bitmap (default format, hardware-aligned), setting the resolution to the current screen resolution or specifying a different resolution for specific uses (for printing, for example).
Or a value that a User can specify.
As mentioned, when a new Bitmap container is created as:
var bitmap = new Bitmap([width], [height]);
the .Net implementation generates a Bitmap with PixelFormat.Format32bppArgb and resolution set to what the Application thinks is the screen DPI. The value returned by Control.DeviceDpi.
A non DpiAware application will most often think it's 96 DPI.
We can nonetheless specify the image resolution using the Bitmap.SetResolution() method (float values, the DPI is always expressed in floating point values).
This Bitmap constructor:
var bitmap = new Bitmap([Stream], true, false))
generates a Format32bppArgb Bitmap, loads the ICM settings (Color Definition) - if any - and skips the validation of the original Bitmap (often used when a lot of image files are read from disk, it's quite faster. Skipping the ICM mapping is also faster, but can produce wrong colors).
We should also suppose that the two images to center inside the new container, may not have the same exact size (or not the same size at all).
Hence we need a new Bitmap that can contain both images, evaluating the maximum dimension of both.
All considered, the original code can be changed as described in the CenterImages() method.
The PictureBox Image can be then set as:
string image1Path = Path.Combine(imgPath, "myImg1.png");
string image2Path = Path.Combine(imgPath, "myImg2.png");
pictureBox1.Image?.Dispose();
pictureBox1.Image = CenterImages(image1Path, image2Path);
to generate a new combined Bitmap using a default 96 DPI resolution. Or as:
pictureBox1.Image?.Dispose();
pictureBox1.Image = CenterImages(image1Path, image2Path, 300.0f);
to generate a new Bitmap with a resolution of 300 DPI.
private Bitmap CenterImages(string sourcePath1, string sourcePath2, float dpi = 96.0f)
{
using (var image1 = new Bitmap(Image.FromStream(
new MemoryStream(File.ReadAllBytes(sourcePath1)), true, false)))
using (var image2 = new Bitmap(Image.FromStream(
new MemoryStream(File.ReadAllBytes(sourcePath2)), true, false))) {
image1.SetResolution(dpi, dpi);
image2.SetResolution(dpi, dpi);
var rect = new Rectangle(0, 0,
Math.Max(image1.Width, image2.Width), Math.Max(image1.Height, image2.Height));
var combinedImage = new Bitmap(rect.Width, rect.Height);
combinedImage.SetResolution(dpi, dpi);
using (var graphics = Graphics.FromImage(combinedImage)) {
graphics.DrawImage(image1, (rect.Width - image1.Width) / 2, (rect.Height - image1.Height) / 2);
graphics.DrawImage(image2, (rect.Width - image2.Width) / 2, (rect.Height - image2.Height) / 2);
}
return combinedImage;
}
}
i try to explain what i need.
1 -My goal condition is to transform black pixels of image in Cartesian points without resize image. (ok, Done)
2 -Second goal condition is to resize image and redo step 1. (ok, i have normalized points with original image size and the job is done when changed width or height!)
3 - Now i need to reduced number of pixels in image to have defined number of DPI in my image to redo step 1. How? I have found the method setResolution(..,..) but how i must change the width and height of my image to obtain the correct resolution in terms of DPI? (see [?????] in code )
var image2 = new Bitmap(canvasWidth, canvasHeight);
image2.SetResolution(200.0f,200.0f); // I need this for example!
using (System.Drawing.Graphics gr = System.Drawing.Graphics.FromImage(image2)) {
gr.SmoothingMode = SmoothingMode.HighSpeed;
gr.InterpolationMode = InterpolationMode.Low;
gr.PixelOffsetMode = PixelOffsetMode.None;
gr.Clear(Color.White);
gr.DrawImage(this.LoadedImage, new System.Drawing.RectangleF(new PointF((float)this.Centre.x, (float)this.Centre.y), new Size(canvasWidth [?????], canvasHeight[??????])));
return image2;
}
If i run over everyone pixel in my new image2 i have the same result like run over OriginalImage. Well,in the end i need to reduced the number of pixels of my image to obtain a defined Dots Per Inch result.
I hope I was clear.
Thanks.
I am using Bing Maps to make some kind of editor. One of the things the editor needs to do as add an Image to the map and have it not scale. I can add the image with out any problem but I cant seem to keep it from scaling when you change your zoom level. Is there a way to set the scale to be fixed when you create the image and add it to the map. I really want to avoid always changing the scale of the image when the zoom level changes as there can be ton of these images on the map.
I did find this question but that did not seem to fix my problem.
here is the code I am using so far:
MapLayer imageLayer = new MapLayer();
Image image = new Image();
image.Height = 150;
BitmapImage myBitmapImage = new BitmapImage();
myBitmapImage.BeginInit();
myBitmapImage.UriSource = new Uri("../../triangle.jpg", UriKind.Relative);
myBitmapImage.DecodePixelHeight = 150;
myBitmapImage.EndInit();
image.Source = myBitmapImage;
image.Opacity = 0.6;
image.Stretch = System.Windows.Media.Stretch.None;
//The map location to place the image at
Location location = new Location() { Latitude = 37.8197222222222, Longitude = -122.478611111111};
//Center the image around the location specified
PositionOrigin position = PositionOrigin.Center;
imageLayer.AddChild(image, location, position);
MapWithPolygon.Children.Add(imageLayer);
The code you provided won't scale the image when zooming. It's possible that it might look slightly scaled due to the background changing but the physical pixel size of the image will not change. The image will only scale if you bounded it to a LocationRect instead of a location.
What is the best way to rotate a image in asp.net
I did use matrix.rotateAt but i can't get it to work so please tell me what is the best way?
I should write out that hate to rotate a image with the image object.
Image myImage = Image.FromFile("myimage.png");
myImage.RotateFlip(RotateFlipType.Rotate180FlipNone);
http://msdn.microsoft.com/en-us/library/system.drawing.image.rotateflip.aspx
Here is some sample code (not written by me - found some time ago here ) that worked for me, as long as you edit some details.
private Bitmap rotateImage(Bitmap b, float angle)
{
//create a new empty bitmap to hold rotated image
Bitmap returnBitmap = new Bitmap(b.Width, b.Height);
//make a graphics object from the empty bitmap
using (Graphics g = Graphics.FromImage(returnBitmap))
{
//move rotation point to center of image
g.TranslateTransform((float)b.Width / 2, (float)b.Height / 2);
//rotate
g.RotateTransform(angle);
//move image back
g.TranslateTransform(-(float)b.Width / 2, -(float)b.Height / 2);
//draw passed in image onto graphics object
g.DrawImage(b, new Point(0, 0));
}
return returnBitmap;
}
Please note, that this may not work "out of the box" - there are some issues with the new bitmap. When you rotate it, it may not fit comfortably in the rectangle of the old bitmap (rectangle bounds b.Width, B.Height).
Anyway this is just to give you an idea. If you choose to do it this way, I'm sure you will be able to work out all the details. I'd post my final code, however I don't have it on me right now...
I would suggest this is the best way
// get the full path of image url
string path = Server.MapPath(Image1.ImageUrl) ;
// creating image from the image url
System.Drawing.Image i = System.Drawing.Image.FromFile(path);
// rotate Image 90' Degree
i.RotateFlip(RotateFlipType.Rotate90FlipXY);
// save it to its actual path
i.Save(path);
// release Image File
i.Dispose();
// Set Image Control Attribute property to new image(but its old path)
Image1.Attributes.Add("ImageUrl", path);
for more