How to process only one part of image by ImageMagick? - c#

I have an image like below and I want to create a distort effect on it. But just the one part of image, not the whole image.
Thanks.

I am assuming you are using Magick.NET (https://magick.codeplex.com) because you added the C# tag.
The example below will first cut out the top 123 pixels of your image and applies a distortion to it. After the distortion it will have to be put on top of the source image.
using (MagickImage image = new MagickImage("0nF6D.png"))
{
using (MagickImage top = image.Clone())
{
top.Crop(image.Width, 123, Gravity.North);
top.Distort(DistortMethod.ScaleRotateTranslate, new double[] { 2, 45 });
image.Composite(top, Gravity.North, CompositeOperator.SrcOver);
image.Write("0nF6D.distorted.png");
}
}

Related

how to get pdf image orientation using itextsharp

Im editing a pdf. The client wants the image inside pdf to be resize and rotated.
so what i did is to extract the image inside the pdf to be able to manipulate the image then insert it again to the the pdf(replacing the old one)
here is the code where i got the code for extracting image
https://psycodedeveloper.wordpress.com/2013/01/10/how-to-extract-images-from-pdf-files-using-c-and-itextsharp/
but when i extract the image to image is rotated 180 degree
i even used the free Spire.PDF to extract the image but the extracted image of the spire.pdf is rotated 90 degree. so how can i get the image orientation of the pdf. so that i can make the image to its original orientation. thank you
There are two relevant factors deciding on the effective rotation of an image, the current transformation matrix at the time the image is drawn (which also fixes the dimensions of the image) and the page rotation.
You can determine these values as shown below in the code you refer to:
...
public static Dictionary<string, System.Drawing.Image> ExtractImages(string filename)
{
var images = new Dictionary<string, System.Drawing.Image>();
using (var reader = new PdfReader(filename))
{
var parser = new PdfReaderContentParser(reader);
ImageRenderListener listener = null;
for (var i = 1; i <= reader.NumberOfPages; i++)
{
// v-- Determine clockwise rotation of page
Console.WriteLine("Page {1} is rotated by {0}°.\n", reader.GetPageRotation(i), i);
// ^-- Determine clockwise rotation of page
parser.ProcessContent(i, (listener = new ImageRenderListener()));
var index = 1;
[...]
}
return images;
}
}
...
public void RenderImage(ImageRenderInfo renderInfo)
{
// v-- Determine transformation matrix of image
Matrix ctm = renderInfo.GetImageCTM();
Console.WriteLine("Found image with transformation matrix:\n{0}\n", ctm);
// ^-- Determine transformation matrix of image
PdfImageObject image = renderInfo.GetImage();
PdfName filter = (PdfName)image.Get(PdfName.FILTER);
[...]
}
...
The output in your case:
Page 1 is rotated by 270°.
Found image with transformation matrix:
792,0001 0 0
0 612 0
0 0 1
Found 1 images on page 1.
Thus, the transformation matrix obviously only scales the image to the appropriate dimensions without rotating it but the page itself is defined to be shown rotated by 270°.
This corresponds to my observations. In particular in contrast to what you said:
but when i extract the image to image is rotated 180 degree
I get an image from your code which has to be rotated by 270° clockwise to be upright.
If you indeed get an image rotated by 180°, you should check the version of iTextSharp you use. The archive on the web site you refer to contains a fairly old version, 5.3.5.0, and bugs might have been fixed in the meantime.

Barcode i25 using ItextSharp

i am using BarcodeInter25 class to make barcode. I am able to make it but its just blur how can it become more sharp ??
also its background white colour is not completely white
My Code:
BarcodeInter25 code25 = new BarcodeInter25();
Rectangle r = new iTextSharp.text.Rectangle(38, 152);
code25.ChecksumText = false;
code25.Code = "some digits";
code25.BarHeight = 2
System.Drawing.Image i = code25.CreateDrawingImage(System.Drawing.Color.Black, System.Drawing.Color.White);
MemoryStream ms = new MemoryStream();
i.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
Image img = Image.GetInstance(ms.ToArray());
ms.Dispose();
Looking at your code, it should be obvious why the barcode is blurry. You convert it to a System.Drawing.Image (making it a raster image) and then you convert it to an iTextSharp.text.Image (but by then the image is already blurry).
The correct way to achieve what you want, is to create an iTextSharp.text.Image straight from the barcode (do not pass through System.Drawing.Image). This can be done like this:
BarcodeInter25 code25 = new BarcodeInter25();
Rectangle r = new iTextSharp.text.Rectangle(38, 152);
code25.ChecksumText = false;
code25.Code = "some digits";
code25.BarHeight = 2;
PdfContentByte cb = writer.DirectContent;
Image img = code25.CreateImageWithBarcode(cb, null, null);
Now the Image object won't be a raster image (with pixels that make the lines blurry), but it will be a true vector image (no pixels, but instructions such as moveTo(), lineTo() and stroke()). Vector data has the advantage that it is resolution independent: you can zoom in and zoom out as much as you want, it will always be sharp.
This is explained in Chapter 10 of my book where you'll find the Barcodes example. In that chapter, you'll also discover the setFont() (or in iTextSharp the Font property). I quote from the API documentation:
public void setFont(BaseFont font)
Sets the text font.
Parameters:
font - the text font. Set to null to suppress any text
So if you don't want to see any text, you can add the following line to the above code snippet:
code25.Font = null;
You should avoid re-sizing by any means. The output is most likely pixel-perfect but when you scale it up/down a bilinear filter will smooth it rendering it blurry.
I had the same exact problem by embedding a QRC code in a PDF and solved it by avoiding a resize.
If you really need a different size apply it programmatically in code by using the correct interpolation algorithm.

How do I crop an ImageSurface in Cairo?

I'm using the Cairo bindings for C#, and I wanted to be able to crop an ImageSurface and put it into a new ImageSurface variable, which I will then use in a seperate subroutine. The question is how would I do this properly.
Here's my code as it stands:
ImageSurface OutputImage = new ImageSurface (Format.Rgb24, (int)RectangleToCropTo.Width, (int)RectangleToCropTo.Height);
using (Cairo.Context cr = new Cairo.Context(OutputImage)) {
cr.SetSource (originalImage);
cr.Rectangle (RectangleToCropTo);
cr.Clip ();
cr.Paint ();
}
As it stands, it does actually crop the image down, and it appears to start at the correct point - but the OutputImage is offset in the x and y axis by the amount of pixels from 0,0 that the top left of the selection is. The area that the image doesn't populate is transparent.
I also tried the following:
ImageSurface OutputImage = new ImageSurface (Format.Rgb24, (int)RectangleToCropTo.Width, (int)RectangleToCropTo.Height);
using (Cairo.Context cr = new Cairo.Context(OutputImage)) {
cr.SetSource (originalImage, RectangleToCropTo.X, RectangleToCropTo.Y);
cr.Rectangle (RectangleToCropTo);
cr.Clip ();
cr.Paint ();
}
This additional two parameters supposedly mark from which point the 'source' should be stored (from my understanding, '40, 40' would mean that 'painting' the image would result in the image from 40, 40 and whatever is to the right of and below it).
However, this neither provides me with a cropped image, but instead includes the troublesome offset and starts drawing from the top left of the image.
I also figured that maybe this would be the solution:
ImageSurface OutputImage = new ImageSurface (Format.Rgb24, (int)RectangleToCropTo.Width, (int)RectangleToCropTo.Height);
using (Cairo.Context cr = new Cairo.Context(OutputImage)) {
cr.SetSource (originalImage, RectangleToCropTo.X, RectangleToCropTo.Y);
cr.Clip ();
cr.Paint ();
}
But to no avail, this simply produces identical results to the previous code chunk.
If any of you could tell me what I'm doing wrong (and it's probably the dumbest of mistakes), I'd appreciate it.
I'm use the Cairo-Sharp that comes with Gtk3.
Thanks :)
You almost got it. Try this:
ImageSurface OutputImage = new ImageSurface (Format.Rgb24, (int)RectangleToCropTo.Width, (int)RectangleToCropTo.Height);
using (Cairo.Context cr = new Cairo.Context(OutputImage)) {
cr.SetSource (originalImage, -RectangleToCropTo.X, -RectangleToCropTo.Y);
cr.Paint ();
}
The important difference is the negative arguments to SetSource. This places the source image so that the (x, y) pixel from the source falls onto the (0, 0) pixel on the target.
Since you target covers all the pixels needed, your rectangle() and clip() calls aren't needed anymore.
clip does not resize the surface, it just masks out anything fur future drawing operations.
Create a new surface of proper size and copy the content of the desired (clipped or not) region.

How to adjust jpeg quality with Magick.Net

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

Emgucv drawn items

I am making a project using Emgucv library, he problem is as follows,
I Capture image
detect feature
extract it
draw it
After that i copy the drawn items in a blank image, now I want find contours inside that new image, but the result is always bull, Why is That?
Thanks in advance
Additional information would be good.
But for you to be able to find the contours, the new image must be converted into a binary image like the ff: (assuming newImage is of type Image)
Image<Gray,byte> binaryImage = newImage.ThresholdBinary(new Gray(1), new Gray(255));
To detect contours and write to resultImage:
for (var contour = binaryImage.FindContours(
CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
RETR_TYPE.CV_RETR_CCOMP);
contour != null;
contour = contour.HNext)
{
resultImage.Draw(contour, new Gray(255), -1);
}

Categories