my problem is that I don´t have much experience with Autocad. Thus I don´t know how to save a project in a good quality image (png?) to insert in a latex document.
Could you give me a hint?
Thank you
Autocad's Publish to Web printers are pretty bad. What I would do is print using DWG to PDF printer or similar (there are a few in autocad's default printer list) then convert that pdf to raster images using a second software like Photoshop, GIMP, etc. There are even small software that convert pdf's to jpgs like TTRPDFToJPG3. If you have a specific idea of what kind of output you're looking for, please feel free to elaborate further. cheers!
If you're looking for a programmatic way to capture the screen, here it is:
using acApp = Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using System.Drawing.Imaging;
using System.Drawing;
namespace ScreenshotTest
{
public class Commands
{
[CommandMethod("CSS")]
static public void CaptureScreenShot()
{
ScreenShotToFile(
acApp.Application.MainWindow,
"c:\\main-window.png",
0, 0, 0, 0
);
ScreenShotToFile(
acApp.Application.DocumentManager.MdiActiveDocument.Window,
"c:\\doc-window.png",
30, 26, 10, 10
);
}
private static void ScreenShotToFile(
Autodesk.AutoCAD.Windows.Window wd,
string filename,
int top, int bottom, int left, int right
)
{
Point pt = wd.Location;
Size sz = wd.Size;
pt.X += left;
pt.Y += top;
sz.Height -= top + bottom;
sz.Width -= left + right;
// Set the bitmap object to the size of the screen
Bitmap bmp =
new Bitmap(
sz.Width,
sz.Height,
PixelFormat.Format32bppArgb
);
using (bmp)
{
// Create a graphics object from the bitmap
using (Graphics gfx = Graphics.FromImage(bmp))
{
// Take a screenshot of our window
gfx.CopyFromScreen(
pt.X, pt.Y, 0,0, sz,
CopyPixelOperation.SourceCopy
);
// Save the screenshot to the specified location
bmp.Save(filename, ImageFormat.Png);
}
}
}
}
}
Source: Taking screenshots of AutoCAD’s main and drawing windows using .NET
Thanks to everyone. I am saving the files in pdf and after I´m using GIMP to convert them in PNG.
Related
As part of a project I am realizing, there are given pdfdocuments which include forms as JPEG Images within A4 pages inside this documents. If have to extract those JPGs out of the PDF. Later on those JPGs are used to build PDF Documents again.
When I simply open up those Documents with any PDFViewer they seem to have no rotation at all, at least it is not visible. So like this icon the have vertical format.
but when I use this sample code to extract the images :
PDDocument doc = PDDocument.load("/path/to/file);
List pages = doc.getDocumentCatalog().getAllPages();
Iterator iter = pages.iterator();
int i = 0;
while (iter.hasNext()) {
PDPage page = (PDPage) iter.next();
System.out.println(page.getRotation());
System.out.println("ROTATION = " + page.getRotation());;
PDResources resources = page.getResources();
Map pageImages = resources.getXObjects();
if (pageImages != null) {
Iterator imageIter = pageImages.keySet().iterator();
while (imageIter.hasNext()) {
String key = (String) imageIter.next();
if(((PDXObjectImage) pageImages.get(key)) instanceof PDXObjectImage){
PDXObjectImage image = (PDXObjectImage) pageImages.get(key);
image.write2file("/path/to/file" + i);
}
i ++;
}
}
}
all extracted JPGs are horizontal format. Further the sysout on the page.rotation tells me that the rotation is set to 270°.
How is that possible? 270 is set, but the PDF is shown vertical (I am no expert on PDF). I even did page.setRotate(0) before extracting the JPGs, but the images still remain horizontally. I read the following Thread telling how to rotate images before drawing them on the pdf. But i need to rotate them before writing them on the filesystem. What is the best way to achieve that?
Unfortunately, I can not attach any of the documents since they are confidential.
Pango syntax supports some text only markup. As far as i can see this does not extend to embedding images as well.
Looking around I cannot find much in the way of an existing implementation, but i havent done pango+cairo work before so i might be missing the obvious community for it.
As far as i can tell a reasonable approach would be to just analyse a string, pull out any tags, create cairo images, and then modify the pango layout around them accordingly.
It also seems like something someone might have done before.
Im specifically looking for an answer on these questions:
Does pango+cairo already solve this and I have just misread the docs?
Has something like this been done before, and where is a reference?
Is this a reasonable approach, or should i try something else, and what?
(also note i am using ruby, so that may affect my options)
I've been through the source of the markup parser and it does not allow for "shape" attributes (the way Pango almost incorporates graphics) but it is possible to do it "by hand".
Since there is absolutely no example code on the Web, here's Pango/Cairo/Images 101.
For a simple demo, I created an 800x400 window, added a GtkDrawingArea and connected up the "draw" signal. Before entering the main program loop, I initialized it with the following code:
PangoLayout *Pango;
void init_drawingArea (GtkWidget *pWidget)
{
cairo_surface_t *pImg = cairo_image_surface_create_from_png ("linux.png");
PangoRectangle r = {0, 0, PANGO_SCALE * cairo_image_surface_get_width (pImg),
PANGO_SCALE * cairo_image_surface_get_height(pImg)};
PangoContext *ctxt = gtk_widget_get_pango_context (pWidget);
PangoAttrList *attList = pango_attr_list_new();
PangoAttribute *attr;
Pango = pango_layout_new (ctxt);
pango_cairo_context_set_shape_renderer (ctxt, render, NULL, NULL);
pango_layout_set_text (Pango, pszLorem, -1);
pango_layout_set_width(Pango, PANGO_SCALE * 800);
attr = pango_attr_shape_new_with_data(&r, &r, pImg, NULL, NULL);
attr->start_index = 0; attr->end_index = 1;
pango_attr_list_insert (attList, attr);
attr = pango_attr_shape_new_with_data(&r, &r, pImg, NULL, NULL);
attr->start_index = 152; attr->end_index = 153;
pango_attr_list_insert (attList, attr);
pango_layout_set_attributes (Pango, attList);
}
The context's shape renderer is set to render () and a PangoLayout is created and initialized. It then creates 2 shape attributes, sets the user data to a cairo surface which we populate from a png file and applies the attributes to characters 0 and 152 of the text.
The "draw" signal processing is straightforward.
gboolean onDraw (GtkWidget *pWidget, cairo_t *cr, gpointer user_data)
{
pango_cairo_show_layout (cr, Pango);
return 1;
}
and the render () PangoCairoShapeRenderFunc function is called as needed:
void render (cairo_t *cr, PangoAttrShape *pShape, gboolean do_path, gpointer data)
{
cairo_surface_t *img = (cairo_surface_t *)pShape->data;
double dx, dy;
cairo_get_current_point(cr, &dx, &dy);
cairo_set_source_surface(cr, img, dx, dy);
cairo_rectangle (cr, dx, dy, pShape->ink_rect.width/PANGO_SCALE,
pShape->ink_rect.height/PANGO_SCALE);
cairo_fill(cr);
}
Taking the current point from cairo, it draws a rectangle and fills it with the image.
And that's pretty much all it does. Images were added as an afterthought and it shows. They are subject to the same rules as any other glyph so they are limited to the equivalent of CSS's display: inline.
I've put the code up at http://immortalsofar.com/PangoDemo/ if anyone wants to play with it. Me, I arrived here trying to get around GtkTextBuffer's limitations. Guess I'll just have to go deeper.
I'm trying to resize an image using im4java. I haven't found any working examples and their JavaDocs are incomplete.
OOTB Java solutions are insufficient and lead to poor quality in the resulting images, despite rendering hint adjustments.
First of all, im4java is an interface for imagemagick and/or graphicsmagick, so you need to install one of them on your computer to get im4java to work.
Here is the code to resize an image:
ConvertCmd cmd = new ConvertCmd();
IMOperation op = new IMOperation();
op.addImage("original_image.jpg");
op.resize(800,600);
op.addImage("resized_image.jpg");
cmd.run(op);
Do you really need this im4java ? I don't know it, but I use to do a pure java transformation :
public BufferedImage scale(final BufferedImage image, final int targetW, final int targetH)
{
final int type = image.getType() == 0 ? BufferedImage.TYPE_INT_ARGB : image.getType();
final BufferedImage scaledImg = new BufferedImage(targetW, targetH, type);
final Graphics2D g = scaledImg.createGraphics();
g.drawImage(image, 0, 0, targetW, targetH, null);
g.dispose();
g.setComposite(AlphaComposite.Src);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
return scaledImg;
}
this code has been working for me for more than 2 years in my project. Let me know if you have any question.
I am in the process of moving a webforms app to MVC3. Ironically enough, everything is cool beans except one thing - images are served from a handler, specifically the Microsoft Generated Image Handler. It works really well - on average a 450kb photo gets output at roughly 20kb.
The actual photo on disk weighs in at 417kb, so i am getting a great reduction.
Moving over to MVC3 i would like to drop the handler and use a controller action. However i seem to be unable to achieve the same kind of file size reduction when rendering the image. I walked through the source and took an exact copy of their image transform code yet i am only achieving 230~kb, which is still a lot bigger than what the ms handler is outputting - 16kb.
You can see an example of both the controller and the handler here
I have walked through the handler source code and cannot see anything that is compressing the image further. If you examine both images you can see a difference - the handler rendered image is less clear, more grainy looking, but still what i would consider satisfactory for my needs.
Can anyone give me any pointers here? is output compression somehow being used? or am i overlooking something very obvious?
The code below is used in my home controller to render the image, and is an exact copy of the FitImage method in the Image Transform class that the handler uses ...
public ActionResult MvcImage()
{
var file = Server.MapPath("~/Content/test.jpg");
var img = System.Drawing.Image.FromFile(file);
var sizedImg = MsScale(img);
var newFile = Server.MapPath("~/App_Data/test.jpg");
if (System.IO.File.Exists(newFile))
{
System.IO.File.Delete(newFile);
}
sizedImg.Save(newFile);
return File(newFile, "image/jpeg");
}
private Image MsScale(Image img)
{
var scaled_height = 267;
var scaled_width = 400;
int resizeWidth = 400;
int resizeHeight = 267;
if (img.Height == 0)
{
resizeWidth = img.Width;
resizeHeight = scaled_height;
}
else if (img.Width == 0)
{
resizeWidth = scaled_width;
resizeHeight = img.Height;
}
else
{
if (((float)img.Width / (float)img.Width < img.Height / (float)img.Height))
{
resizeWidth = img.Width;
resizeHeight = scaled_height;
}
else
{
resizeWidth = scaled_width;
resizeHeight = img.Height;
}
}
Bitmap newimage = new Bitmap(resizeWidth, resizeHeight);
Graphics gra = Graphics.FromImage(newimage);
SetupGraphics(gra);
gra.DrawImage(img, 0, 0, resizeWidth, resizeHeight);
return newimage;
}
private void SetupGraphics(Graphics graphics)
{
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.CompositingQuality = CompositingQuality.HighSpeed;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.HighSpeed;
}
If you don't set the quality on the encoder, it uses 100 by default. You'll never get a good size reduction by using 100 due to the way image formats like JPEG work. I've got a VB.net code example of how to set the quality parameter that you should be able to adapt.
80L here is the quality setting. 80 still gives you a fairly high quality image, but at DRASTIC size reduction over 100.
Dim graphic As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(newImage)
graphic.InterpolationMode = Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
graphic.SmoothingMode = Drawing.Drawing2D.SmoothingMode.HighQuality
graphic.PixelOffsetMode = Drawing.Drawing2D.PixelOffsetMode.HighQuality
graphic.CompositingQuality = Drawing.Drawing2D.CompositingQuality.HighQuality
graphic.DrawImage(sourceImage, 0, 0, width, height)
' now encode and send the new image
' This is the important part
Dim info() As Drawing.Imaging.ImageCodecInfo = Drawing.Imaging.ImageCodecInfo.GetImageEncoders()
Dim encoderParameters As New Drawing.Imaging.EncoderParameters(1)
encoderParameters.Param(0) = New Drawing.Imaging.EncoderParameter(Drawing.Imaging.Encoder.Quality, 80L)
ms = New System.IO.MemoryStream
newImage.Save(ms, info(1), encoderParameters)
When you save or otherwise write the image after setting the encoder parameters, it'll output it using the JPEG encoder (in this case) set to quality 80. That will get you the size savings you're looking for.
I believe it's defaulting to PNG format also, although Tridus' solution solves that also.
However, I highly suggest using this MVC-friendly library instead, as it avoids all the image resizing pitfalls and doesn't leak memory. It's very lightweight, free, and fully supported.
I'd like to create programmatically a random X height and Y width bitmap file.
The content, for me, is irrelevant. It could be all white, empty. What is important is the dimension.
How to do it using Windows API?
You wish to create a Bitmap File using the windows API? There is no specific helper for this. a BMP file however is very simple:
Write out a BITMAPFILEHEADER struct.
Write out a BITMAPINFO struct.
Write out an array of bytes, enough to hold the format and dimensions described in the BITMAPINFO struct.
The MSDN has an Article with sample code demonstrating how.
I suppose you have Microsoft .NET 2.0 Framework installed. (1.1 is also usable).
Using Notepad, create test.cs file with this code:
namespace test
{
class Program
{
static void Main(string[] args)
{
if (args.Length == 3)
new System.Drawing.Bitmap(System.Convert.ToInt32(args[0]), System.Convert.ToInt32(args[1]))
.Save(args[2] + ".bmp", System.Drawing.Imaging.ImageFormat.Bmp);
else
System.Console.WriteLine("Usage: test.exe 100 200 filename");
}
}
}
Then create test.cmd file with this code:
#echo off
%windir%\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:exe test.cs
Execute test.cmd
Execute text.exe
In .Net you can just new up a Bitmap object:
Image myImage = new Bitmap(width, height);
GDI+ includes commands to load/save BMP images in C++. This sample code shows how to load and save images: Converting a BMP Image to a PNG Image. The Bitmap class also has a ctor that takes a width, a height and a pixel format to create empty images.
If you really insist on making an image with windows API,you should use Gdi32.dll
In C# just call
Import dll file into your assembly, so you can use external methods in
DllImport["Gdi32.dll"]
HBITMAP CreateCompatibleBitmap(
HDC hdc,
int nWidth,
int nHeight
);
Then call Bitmap class from this Bitmap like
Bitmap bmp = Bitmap.FromHbitmap( nameOfBitmap );
bmp.Save("C:\NewImage.jpg");
There is an example in msdn page here