Converting PDF/SVG to PNG with antialias off using Magick++ - svg

I've tried to convert a SVG file to PNG with antialiasing off in Magick++ but I wasn't successful. But I was able to convert the SVG file to PDF with another program and the use the ImageMagick convert command to convert the PDF file to PNG.
How can I use ImageMagick to do it? The command I use for converting PDF to PNG is this:
convert +antialias -interpolate Nearest -filter point -resize 1000x1000 "img.pdf" PNG24:"filter.png"
Is there any way to use Magick++ to do that or better, convert SVG to PNG directly with antialiasing off?
Thanks in advance.
Edit:
The answer given in this post doesn't work for me. Possible because I'm using a colored SVG instead of 1-bit alpha channel. Also I mentioned in my question that I'm also looking for a way to do this in Magick++.

Magick++ has the Magick::Image::textAntiAlias & Magick::Image::strokeAntiAlias methods available, but they would only be useful if your parsing the SVG and rebuilding the image (i.e. roll-your-own SVG engine) one SVG element at a time.
As #ccprog pointed out in the comments; once the decoder utility rasters the vectors, the damage is done & setting the flags would not have an effect on the resulting resize.
Without seeing the SVG, I can only speculate what the problem is. I would suggest setting the document size before reading the SVG content.
For example, read the image at a smaller size than resample up.
Magick::Image img;
img.size(Magick::Geometry(100, 100)); // Decode to a small context
img.read("input.svg");
img.interpolate(Magick::NearestInterpolatePixel);
img.filterType(Magick::PointFilter);
img.resize(Magick::Geometry(600, 600));
img.write("PNG24:output#100x100.png");
Or render at larger size then the finial image.
Magick::Image img;
img.size(Magick::Geometry(1000, 1000)); // Decode to a larger context
img.read("input.svg");
img.interpolate(Magick::NearestInterpolatePixel);
img.filterType(Magick::PointFilter);
img.resize(Magick::Geometry(600, 600));
img.write("PNG24:output#1000x1000.png");
Update from comments
For Postscript (PDF) & True-Type antialiasing, you would set Magick::Image::textAntiAlias (or Magick::Image::antiAlias if using IM6) to false. Just ensure that the density is set to allow any overhead.
Magick::Image img;
img.density(Magick::Point(300));
if (MagickLibVersion < 0x700) {
img.antiAlias(false);
} else {
img.textAntiAlias(false);
}
img.interpolate(Magick::NearestInterpolatePixel);
img.filterType(Magick::PointFilter);
img.read("input.pdf");
img.resize(Magick::Geometry(1000, 1000));
img.write("PNG24:output.png");

Related

Add SVG image to PdfSignatureAppearance with iText7

I want to add a SVG image to PdfSignatureAppearance. The method setSignatureGraphic has an ImageData parameter now in iText7. I couldn't find a way to create an imageData from SVG because ImageDataFactory is not supporting this format.
Can you please guide me on how to do that?
Note that with iText5 I was able to add svg after converting it to PDF and import it to a PDFTemplate then create an image after instantiate the PDFTemplate. setSignatureGraphic was accepting com.itextpdf.text.Image as parameter
Your question could be split into 2 more precise and simple ones:
How to process an SVG with iText?
How to create an ImageData instance out of the result of point 1?
As for question 1: one can use SvgConverter class (part of iTextCore's svg module). Unfortunately there are only PDF-related methods there: an SVG could be converted either to Image (class of layout module), or to PdfFormXObject (again PDF-related) or to a PDF file.
// to PDF
SvgConverter.convertToImage(new FileInputStream(sourceFolder + "your_svg.svg"), signer.getDocument()); // the mentioned `signer` is the instance of PdfSigner which you use to sign the document
// to Image
SvgConverter.convertToImage(new FileInputStream(sourceFolder + "your_svg.svg"), new File(destinationFolder + "svgAsPdf.pdf"));
As for question 2, there are several answers:
a) Suppose that you want to use this Image as the PdfSignatureAppearance's graphics data. For now the class doesn't provide a convenient setter, however, you could use some low level methods - either getLayer0 or getLayer2 to get the signature's background or foreground. They are represented by PDfFormXObject, hence you can use Canvas to add your image to them:
Image svg = SvgConverter.convertToImage(new FileInputStream(sourceFolder + "your_svg.svg"), signer.getDocument());
Canvas canvas = new Canvas(appearance.getLayer0(), signer.getDocument());
canvas.add(svg);
canvas.close();
b) Suppose that your goal is to use the rendered bitmap as the PdfSignatureAppearance's graphics data. Then there is a specific iText product - pdfRender - which converts PDF files to images. The following code could be applied:
PdfToImageRenderer.renderPdf(new File(destinationFolder + "svgAsPdf.pdf"), new File(folderForTheResultantImage));
Now you can create an ImageData instance out of the resultant image file (by default a PDF is converted to a series of images with the format "pdfnamePAGE_NUMBER.jpg", but one could customize either the name or the output image format). In your case the PDF consist of just one page (which represents the converted SVG) and its name is "image1.jpg". The rest is obvious:
appearance.setSignatureGraphic(ImageDataFactory.create(destinationFolder + "image1.jpg"));

Python extract part of SVG to PNG

I have been doing a ton of searching but cant quite find the answer to this one.
I have a series of relatively simple SVG images. I have drawn SVG rectangles over key areas of the images that I am interested in and would now like to extract those areas as PNG images. I have no idea the best way to approach this problem.
Idea 1) Convert the whole SVG to PNG then use say PIL to crop the image down after somehow converting the SVG rect coordinates to PNG coordinates. I am starting to work towards this method now, but I am hoping there is a better, and/or easier way to do this!
I am using Python 3.7 for this.
Edit 1:
This is a screen shot of what I am looking at. The original image is SVG, I would like to extract the areas under the green rectangles as PNG images.
Edit 2:
Working from Idea 1, I have the following code that basically sets the viewBox on the SVG image to one of the green rectangles, then sets the width and height of it. From there I am using CairoSVG to export the SVG as PNG.
import cairosvg
import xml.etree.ElementTree as ET
...
with gzip.open(fileObj.filePath,'rb') as file:
svg=file.read()
svg=svg.decode('utf-8')
svgRoot=ET.fromstring(svg)
ET.register_namespace("","http://www.w3.org/2000/svg")
ET.register_namespace('xlink', "http://www.w3.org/1999/xlink")
annots = meta['annots']
for a in annots:
r = ET.fromstring(a['g'])
vb=" ".join([r.get('x'),r.get('y'),r.get('width'),r.get('height')])
svgRoot.set("viewBox",vb)
svgRoot.set("width",'128px')
svgRoot.set("height",'128px')
svg = ET.tostring(svgRoot, encoding="unicode")
cairosvg.svg2png(svg,write_to="/home/test.png")
Unfortunately it is EXTREMELY slow! On the order of more than a minute to extract two PNGs. The SVG files are quite large (2 - 3 mb zipped) and very detailed. I am not certain how CairoSVG works, but does it render everything in the SVG even if it isnt visible before saving the visible part to PNG?
Any advise on optimising or speeding this up would be a huge help.
This worked for me in the end, though it is quite slow on larger SVG images:
import gzip
import cairosvg
import xml.etree.ElementTree as ET
...
with gzip.open(fileObj.filePath,'rb') as file:
svg=file.read()
svg=svg.decode('utf-8')
svgRoot=ET.fromstring(svg)
ET.register_namespace("","http://www.w3.org/2000/svg")
ET.register_namespace('xlink', "http://www.w3.org/1999/xlink")
annots = meta['annots']
for a in annots:
r = ET.fromstring(a['g'])
vb=" ".join([r.get('x'),r.get('y'),r.get('width'),r.get('height')])
svgRoot.set("viewBox",vb)
svgRoot.set("width",'128px')
svgRoot.set("height",'128px')
svg = ET.tostring(svgRoot, encoding="unicode")
cairosvg.svg2png(svg,write_to="/home/test.png")

Want to find the way to generate the thumbnail image for a given pdf file

I'm currently looking for a way to generate the thumbnail image for a given pdf file, which shows several pages in the same image. The output should like what shows in the arxiv sanity website. I want to know if there is any npm package which supports this functionality. Thanks.
In ImageMagick command line, you can do that as follows. Suppose you want 8 pages from the PDF.
Input PDF from http://www.arxiv-sanity.com:
convert image.pdf[0-7] -thumbnail 140x140 -background white +smush 20 -bordercolor white -border 10 result.jpg
This takes the first 8 pages, makes thumbnails of size 140x140 and appends them side-by-side with a 20 pixels white spacing between them and adds a 10 pixel white border around it all.
Sorry, I do not know Node.js. But apparently there is a module that integrates ImageMagick. See https://github.com/yourdeveloper/node-imagemagick
var PDFImage = require("pdf-image").PDFImage; //pdf to image convert
var pdfImage = new PDFImage("1120.pdf");
pdfImage.convertPage(0).then(function (imagePath) {
},(err)=>{
console.log("err",err)
})
//##jimp Npm use thumbnail image generate
//if auth error Follow this step :
-> In /etc/ImageMagick-6/policy.xml (or /etc/ImageMagick/policy.xml) find the following line
->
and change it to allow reading and writing by the PDF coder in ImageMagick:

how to correct the orientation of the image with ITK-VTK

I am a beginner in VTK ITK, I am trying to read a DICOM series with ITK and display with VTK but I had pictures upside down, I tried to read a single image (JPG) with ITK and visualuser with VTK it is the same problem, so I had the idea of ​​treating the image on photoshop ie I applied to the original image rotation (vertical symmetry of the work area) and I did the reading with ITK and display with VTK, the image is displayed in the correct orientation, infact ITK keeps the orientation of the image, but the problem is at VTK, it is which displays the image upside down, I searched all over the internet I have not found a solution or a method or not even an idea, I encountered the same problem in many forums but there is no response, I count on your help, I can not apply any image processing to find a solution to this problem.
Please Help! thank you in advance
Ideally you should re-orient your camera in VTK so that it is suited for medical image visualization. (The default camera in VTK uses the computer graphics conventions).
If you want a quick hack, you can copy-paste the following code in ITK:
FlipFilterType::Pointer flipperImage = FlipFilterType::New();
bool flipAxes[3] = { false, true, false };
flipperImage = FlipFilterType::New();
flipperImage->SetFlipAxes(flipAxes);
flipperImage->SetInput( image );
flipperImage->Update();
I use a rapid way to set the orientation:
imageActor->SetOrientation(180,0,0);
No need to add filter.
Here's an example of how I would do it. I'm not sure what classes you are using, so I cannot be specific.
vtkSmartPointer<vtkImageData> result = vtkSmartPointer<vtkIMageData>::New();
result->DeepCopy(YourImage); //DeepCopy your image to result
rImage->Update();
double val;
int i = 0;
for(vtkIdType f = result->GetNumberOfPoints()-1; f > -1; f--)
{
val = YourImage->GetPointData()->GetScalars()->GetTuple1(f);
result->GetPointData()->GetScalars->SetTuple1(i,val);
i++;
}
result->Update();
//Now Visualize your image

How do I convert Bayer to RGB using OpenCV and vice versa

OpenCV provided function to convert Bayer to RGB, but how to use this CV_BayerBG2BGR , and other similar function?
I used code below, but the error appears stated invalid channel number. Since I use RGB image as originalImage, anyway how this function actually works?
void main(){
// Declare and load the image
// Assume we have sample image *.png
IplImage *originalImage = cvLoadImage("bayer-image.jpg",-1);
// The image size is said to be 320X240
IplImage *bayer2RGBImage;
bayer2RGBImage = cvCreateImage(cvSize(100,100),8,3);
cvCvtColor(originalImage,bayer2RGBImage,CV_BayerBG2BGR);
//Save Convertion Image to file.
cvSaveImage("test-result.jpg",bayer2RGBImage);
//Release the memory for the images that were created.
cvReleaseImage(&originalImage);
cvReleaseImage(&bayer2RGBImage);}
Furthermore, I'd like to convert common RGB image to bayer format (let say bilinear) too, whether openCV provide this function as well?
any help would be really appreciated.
Thanks in advance.
Unfortunately OpenCV does not provide BGR to Bayer conversion. Only backward conversion is available.
If you need a conversion to Bayer format then you should implement this conversion yourself or use another library.

Resources