How do I use the AutoRotate plugin in a c# console application? I thought I'd be able to do something like settings.AutoRotate = true; like I can change the fit mode to use the seam carving plugin.
I've tried settings.Add("autorotate","true") to the keycollection, as well as other keynames AutoRotate and autoRotate.
I'm using it in a simple method.
new AutoRotate().Install(ImageResizer.Configuration.Config.Current);
...
protected static Image ResizeImage(Image image, double scaleFactor)
{
var settings = new ResizeSettings
{
Scale = ScaleMode.Both,
Width = (int)Math.Floor(Image.Width * scaleFactor),
Height = (int)Math.Floor(Image.Height * scaleFactor),
Mode = FitMode.None,
Format = "png"
};
settings.Set("autorotate", "true");
return ImageBuilder.Current.Build(image, settings, true);
}
After a lot of research, I've found the error that I'm making, and reveals a nice little "hidden feature" of .Net!
When an image is read into the Bitmap object, the meta data is erased, so, by accepting an Image object, the data about the orientation is lost and auto rotate doesn't kick in. So, passing the image filename instead of the image object, and my code above above works!
Thanks guys!
Related
I've got a strange problem. There is an image. Unfortunately it's too big to show it in question. But you can download it. If you can't do it from OneDrive this is another way.
This image seems to be ordinary, but it's not.
When we open properties we will see this:
We need to keep in mind dimensions of this picture: Width is 3000px and Height is 4000px. It looks correct because image is portret.
Then lets try to read it with C#:
private static void TestImage()
{
using (FileStream file1 = new FileStream("DSC_2446.JPG", FileMode.Open))
{
Console.WriteLine("DSC_2446.JPG :");
using (var img1 = System.Drawing.Image.FromStream(file1))
{
Console.WriteLine($" Width = {img1.Width}");
Console.WriteLine($" Height = {img1.Height}");
}
}
Console.Read();
}
And in results we see some magic!!!
So I've got completely wrong values. Values are switched between properties.
Does someone know why it can happens and how to detect/fix this behavior?
The problem is the EXIF version. You can use this site to get the real data https://exif.tools/meta/Exif-Version/0231 and you will see
Also according to this Post you can get your image's orientation by
var orientation = (int)img1.GetPropertyItem(274).Value[0];
//orientation = 6
the value 6 means rotate 90 degrees.
There is the reference of the value 6. https://exiftool.org/TagNames/EXIF.html
How can I add a png image as a watermark to a larger image using Xamarin.iOS c# and save the output to the device?
I figured out the Xamarin.Android version from another question posted here.
Thanks in Advance!!
Using an image context, you can draw the original, then the watermark at the necessary location and obtain a new image from the context.
ImageContext example:
var originalImage = UIImage.FromBundle("buymore.jpg");
var watermarkImage = UIImage.FromFile("vs.png");
UIGraphics.BeginImageContextWithOptions(originalImage.Size, true, 1.0f);
originalImage.Draw(CGPoint.Empty);
watermarkImage.Draw(new CGRect(new CGPoint(200, 200), watermarkImage.Size));
var processedImage = UIGraphics.GetImageFromCurrentImageContext();
If your original and watermark images are the same size, you can use a CIFilter (CISourceOverCompositing) to "overlay" one image on top of another (assuming your watermark has a white or alpha background. This is my preferred method due to the speed.
CISourceOverCompositing example:
UIImage processedimage;
using (var filter = new CISourceOverCompositing())
{
filter.Image = new CIImage(UIImage.FromBundle("vs.png"));
filter.BackgroundImage = new CIImage(UIImage.FromBundle("buymore.jpg"));
processedimage = UIImage.FromImage(filter.OutputImage);
}
I am trying to set the image quality of two images appended to one another to 10% and resize the images to 40x40.
using (var images = new MagickImageCollection {designFile, swatchFile})
{
MagickImage sprite = images.AppendHorizontally();
sprite.Format = MagickFormat.Jpeg;
sprite.SetOption(MagickFormat.Jpeg, "quality", "10%");
sprite.SetOption(MagickFormat.Jpeg, "size", "40x40"); ;
sprite.Write(spriteFile);
}
Unfortunately the SetOption and Format calls don't seem to be affecting the file that is written to sprite.Write()?
The method SetOption is the same as -define in ImageMagick. And this method will be renamed to SetDefine in the next release. The following resizes your image to 40x40 and uses a quality of 10%.
using (MagickImage sprite = images.AppendHorizontally())
{
sprite.Format = MagickFormat.Jpeg;
sprite.Quality = 10;
sprite.Resize(40, 40);
sprite.Write(spriteFile);
}
If you need more help feel free to post another question here: https://magick.codeplex.com/discussions
Assuming that you know about drop box(no problem if you don't know).
In my desktop application there is an upload functionality. I want to mark correct sign on file icon at bottom left after upload.(same as Dropbox does).
How can I do that? What's that trick?
DropBox is a shell extension, so it uses the OS icons and overlay them.
In your case, if it's a desktop application you can overlay your icons using something similar to this:
private static object mOverlayLock = new object();
public static Image GetOverlayedImage(Image baseImage, Image overlay)
{
Image im = null;
lock (mOverlayLock)
{
try
{
im = baseImage.Clone() as Image;
Graphics g = Graphics.FromImage(im);
g.DrawImage(overlay, 0, 0, im.Width, im.Height);
g.Dispose();
}
catch
{
// LOG EXCEPTION!!
}
}
return im;
}
This is a basic example. You can also play with the overlay position, (topleft, middleleft ...), that requires a little bit more programming.
Then, from your application you can call this method to get the result image. For example
...
Image folderIcon = GetFolderIcon();
Image upToDateOverlay = GetUpToDateOverlay();
Image folderUptoDate = GetOlverlayedImage(folderIcon, upToDateOverlay);
// Then assign this image to your control item (treelistnode, listViewnode, whatever)
I'm rendering a WPF canvas to an image and sticking it on the clipboard.
If the canvas is small (< 900px square) it all works fine.
I have a larger canvas (3000+px square) and the clipboard is empty (paste option disabled in photoshop/word etc)
var transform = canvas.LayoutTransform;
canvas.LayoutTransform = null;
var size = new Size(canvas.Width, canvas.Height);
canvas.Measure(size);
canvas.Arrange(new Rect(size));
var renderBitmap = new RenderTargetBitmap((int) size.Width, (int) size.Height, 96d, 96d, PixelFormats.Pbgra32);
renderBitmap.Render(canvas);
canvas.LayoutTransform = transform;
Clipboard.SetImage(renderBitmap);
I've not found if there is a threshold size that causes this to break.
3140 x 1903 doesnt work, 3140 x 317 does
Whats going on?
Thanks
It turns out that in order to store an image to the clipboard, the image is automatically converted into uncompressed bitmaps in several formats (BMP, DIB, etc.). So when you have a 10MP image that takes up 40MB uncompressed (8-bit RGBA), it could take 200MB of memory to store on the clipboard -- just in case somebody might want it in one of those other formats.
What you might be able to do is put it on the clipboard yourself without as much overhead. If you use Reflector, you'll see that Clipboard.SetImage looks like this:
public static void SetImage(Image image)
{
if (image == null)
{
throw new ArgumentNullException("image");
}
IDataObject data = new DataObject();
data.SetData(DataFormats.Bitmap, true, image); // true means autoconvert
Clipboard.SetDataObject(data, true); // true means copy
}
If you make your own version of the SetImage function with one or both of the true instances set to false, you may be able to overcome some of the unnecessary copying and be able to put a larger image on the clipboard.