I included an image as a resource following this post:
How to create and use resources in .NET
I am using PDFSharp library to create a PDF. The method to draw an image, requires the path of the image. How do I get the path of Properties.Resources.Image?
Or is there another way to do this?
The Properties.Resources.Image is in-memory resource.
You can save Image to temp file and the get the path.
var path = Path.GetTempPath();
Properties.Resources.logo.Save(path);
Above uses Bitmap.Save
You can actually create an image, without saving it, using XImage.FromGdiPlusImage():
var image = XImage.FromGdiPlusImage(Properties.Resources.logo);
As of PDFsharp/MigraDoc 1.50 beta 2 and newer you no longer need a path when using MigraDoc. It was already mentioned that PDFsharp does not need a filename, as images can be read from e.g. streams.
MigraDoc still requires a string. You encode the image data as a string (BASE64 format) and pass that string as a filename.
See also:
http://pdfsharp.net/wiki/MigraDoc_FilelessImages.ashx
Related
I'm writing a WinForms application. I created a Google Doc template file that contains placeholders like {{name}} for various text elements. I can successfully make a copy of this document and use the BatchUpdateDocumentRequest to modify them just fine.
However, I also have an embedded image in the document. I can obtain the objectId for this image just fine. I either want to replace this image with another or remove it from my template and then append my new image to the end of the document. In both cases, the InsertInlineImage or ReplaceImage classes require a URI of the image to insert or replace with. This is where I have an issue.
The image itself has been captured from a control on the WinForms. Its actually a chart. I've saved the image in PNG format since I know that is one of the formats supported by Google drive/docs. I figured in order to use it in the batch update, I would need to upload it first, so I did and got its file id and webcontentlink back in the response.
I'm not locked into any particular way of doing this. I originally tried creating an HTML file, uploading but then it would strip the image from it, so became useless, so I switched gears to using a Google Doc as my template and just try to replace elements in it instead. This went well until I got to the image.
Essentially no matter what I try to specify as the URI, it says the file in not in a supported format.
As far as I can tell, Google expects the URI to actually end in .png or be a real link versus a download URL you'd get from Google Drive.
Here is an example of the code I'm using to attempt to replace the image. The strImageObjectId is the objectId of the Embedded Object image in the template document copy that I want to replace. The Uri is what Google needs to pull the new image from. I'm happy to pull it from my local computer or Google Drive if only I could get it to accept it somehow.
BatchUpdateDocumentRequest batchUpdateRequest = new BatchUpdateDocumentRequest {
Requests = new List<Google.Apis.Docs.v1.Data.Request>()
};
request = new Google.Apis.Docs.v1.Data.Request {
ReplaceImage = new ReplaceImageRequest() {
ImageObjectId = strImageObjectId,
Uri = strChartWebContentLink
}
};
batchUpdateRequest.Requests.Add(request);
DocumentsResource.BatchUpdateRequest updateRequest =
sDocsService.Documents.BatchUpdate(batchUpdateRequest, strCopyFileId);
BatchUpdateDocumentResponse updateResponse = updateRequest.Execute();
I'm happy to use whatever method will get me to a point where I an end up with a Google Doc on Google Drive that was based on a template in which I can replace various text elements, but most importantly add/replace an image.
Thanks so much for the advice.
I got to the point were I believe I was specifying the URI correctly, but then I started getting an access forbidden error instead.
I didn't have time to hunt this one down, so I went back to creating an HTML template with my image, uploading as a Google Doc, exporting to PDF, and then uploading as a PDF. This ended up working because originally I was using a BMP as the file format and that is not supported by Google Docs, so I changed to a PNG instead and it worked just fine.
I think Google Docs needs to add the ability to add an image using a MemoryStream or some other programmatic base64 resource instead of purely being based on URIs and running into temporary upload or permission issues.
Hey I'm doing the same thing with you,
and I got this, by modify the download link format.
from this:
https://docs.google.com/uc?export=download&id={{YOUR GDRIVE IMAGE
ID}
to this
https://docs.google.com/uc?export=view&id={{YOUR GDRIVE IMAGE ID}
e.g :
uri: "https://docs.google.com/uc?export=view&id=1cjgyHqtYSgS0CBT4x-9eQIHRzOIfGgv-"
but the image should be set for public privilege
I have the "image.png" fileless image included in my WPF C# project as "embedded resourse". The full name of such image is "myapplication.image.png".
I am using such image in a document generated via MigraDoc. However, the document generated contains all the contenent that I planified, but a gray square within wrote "image not found" instead of image "image.png".
In order to use "image.png" in my document via MigraDoc, I added the file "image.png" as embedded resource to my project. Therefore, I followed this sample to include this image in the document.
My resulting code looks like the following:
byte[] imageStream = LoadImage("myapplication.image.png");
string imageFilename = MigraDocFilenameFromByteArray(imageStream);
Image image = para.AddImage(imageFilename);
Where "LoadImage" and "MigraDocFilenameFromByteArray" methods are coded as in the sample.
What am I missing?
Would someone provide a pointer, please?
If using NuGet, please note that you have to check 'Include prerelease' in order for MigraDoc v1.50.x to show up in the list of packages. Note that this is the 'Version', not the 'Runtime Version' number (right-click your MigraDoc reference and check properties). The most recent stable release is only v1.32.x.
As suggested by #User241.007, the issue was using 1.32 and nor 1.50 or later. Hence, everything is working now that I removed 1.32 and installed 1.50 via package manager.
I've been working on an application to read images from multiple word files and store them in one single word file using Microsoft.Office.Interop.Word in C#
EDIT: I also need to save a copy of the images on the file system, so I need the image in a Bitmap or similar object.
This is my implementation so far, which works fine:
foreach (InlineShape shape in doc.InlineShapes)
{
shape.Range.Select();
if (shape.Type == WdInlineShapeType.wdInlineShapePicture)
{
doc.ActiveWindow.Selection.Range.CopyAsPicture();
ImageData = Clipboard.GetDataObject();
object _ob1 = ImageData.GetData(DataFormats.Bitmap);
bmp = (Bitmap)_ob1;
images[i++] = bmp;
/*
bmp.Save("C:\\Users\\Akshay\\Pictures\\bitmaps\\test" + i.ToString() + ".bmp");
*/
}
}
I have:
Selected the images as InlineShapes
Copied the shape into Clipboard
Stored the shape in the Clipboard in a DataObject
Extracted the shape from the DataObject in Bitmap format and stored in a Bitmap object.
I've been told to refrain from using Clipboard in Word automation and use the Word APIs instead.
I've read up on it and found an SO answer stating the same.
I looked up many implementations of reading images from Word files on MSDN, SO etc. but could not find any without using clipboard.
How do I read images from Word files using the Word APIs from Microsoft.Office.Interop.Word namespace alone without using Clipboard ?
Word documents in the Office Open XML file format store images in Base64. So it should be possible to extract that information and convert/stream it to a file. You can access the information when the document is open in the Word application using the Range.WordOpenXML property.
string shapeBase64 = shape.Range.WordOpenXML;
This will return the entire Word Open XML in the flat file OPC format. In other words, it won't contain only the picture in Base64, but the entire zip package definition as XML that surrounds it. In my quick test, the tag the contains the actual Base64 is
<pkg:binaryData>
That's a child element of
<pkg:part pkg:name="/word/media/image1.jpg" pkg:contentType="image/jpeg" pkg:compression="store">
Note that it would also be possible for you to get the entire document's WordOpenXML in one step:
document.Content.WordOpenXML
but might then need to understand the way the InlineShapes in the document body are linked to the actual information in the "media" part.
And it would be possible, of course, to work directly with the Zip Package (using the Open XML SDK, perhaps) instead of opening the document in the Word.Application.
I'm trying to convert a .png file to a .pcx file. The scenario is the following:
I'm using a TSC TTP-343C label printer. On the labels I have to print images. TSC provides a library documentation for developers. Since I can only print images on those labels using pcx files I have to convert all the images to pcx images. Any other format or even incorrect pcx format (e.g. if the user just renamed the file ending) will not be printed on the label.
I've seen this post linking to the Magick library. In this post, the OP is trying to convert a bmp file to a pcx file which is not exactly what I try to achieve. I looked at the Magick documentation about converting images. I tried to convert the images like:
using (MagickImage img = new MagickImage(png)) // png is a string containing the path of the .png file
{
img.Format = MagickFormat.Pcx;
img.Write(pcx); // pcx is a string containing the path of the new .pcx file
}
Unfortunately this is not saving the image correctly. The label printer still cannot print the image on the label. I tried printing a correct pcx file and this worked fine. So I guess the only reason why it's still not working is that the converted file is not a real pcx file.
Is there a way to do such a conversion? If yes, how can I achieve that? My application is a windows forms application, written in C# using .NET framework 4.5.2.
EDIT:
Here you can see an example how to print a label with a pcx file:
TSC.openport(sPrinterName);
TSC.setup("100", "100", "4", "8", "1", "3.42", "0");
TSC.clearbuffer();
TSC.downloadpcx(#"\\PathToPcxFile\test.pcx", "test.pcx");
TSC.sendcommand("PUTPCX 35," + y + ",\"test.pcx\"");
TSC.printlabel("1", "1");
TSC.closeport();
This code works fine on real pcx files. The methods of the TSC library can you find here.
downloadpcx(a,b)
Description: Download mono PCX graphic files to the printer Parameter:
a: string; file name (including file retrieval
path)
b: string, names of files that are to be downloaded in the
printer memory (Please use capital letters)
Source: http://www.tscprinters.com/cms/upload/download_en/DLL_instruction.pdf
EDIT II:
A pcx file which is working (created using photoshop) looks like this (if it helps you):
PCX files are (at best) palette-based.
So to create a valid pcx output you need to add this one line:
using (MagickImage image = new MagickImage(sourcePng))
{
image.Format = MagickFormat.Pcx;
image.ColorType = ColorType.Palette; // <----
image.Write(targetPcx);
}
Your image as pcx file
A DLL file contains some images inside PNG resource type.
I can view the PNG images in softwares like Resource Hacker, Anolis Resourcer & Resource Tuner. Check this screenshot of Anolis Resourcer for more details:
Can someone tell me how do I get the PNG image no. 5220 from the DLL file and put it inside a PictureBox? I don't think APIs like LoadImage or LoadBitmap will work.
// get the assembly containing the image
var assembly = Assembly.GetExecutingAssembly();
// set the picturebox image to read the embedded resource
pictureBox1.Image = Image.FromStream(
assembly.GetManifestResourceStream("AssemblyName.test.png")
);
where AssemblyName.test.png is the fully qualified name of the embedded resource inside the assembly.
UPDATE:
It seems that you are trying to extract resources from a native assembly. You may take a look at the following article which illustrates how this could be done using P/Invoke.
The link that Darin posted (which has consequently been marked as the answer) does not contain functional code. I've evaluated the code posted there (http://khason.net/blog/how-to-load-unmanaged-native-resources-from-managed-c-code/) and found that it does not work properly for any Bitmap image embedded in any win32 dll as a bitmap resource.
Additionally, Hans Passant leaves off a myriad of steps effectively rendering his post useless.
The only somewhat close solution that I've been able to find comes from an article written in 2004 for the XP Theme dll junk. You can find the 'GetResourcePNG' method in ThemeManager.cs here http://www.codeproject.com/KB/miscctrl/XPTaskBar.aspx
However, it should be noted that I've been having a lot of difficulty with this method, as the call to bitmap.RotateFlip(RotateFlipType.Rotate180FlipX); causes memory issues when trying to access pngs within authui.dll on my system
Update:
I've found the code listed here (http://www.vbaccelerator.com/home/NET/Code/Controls/Explorer_Bar/ExplorerBar_Control_Source_Code.asp) to be by far the most functional, produce the fewest errors and produces the fastest results. The code is written in c# even though the domain name would indicate otherwise. Using the two classes; ImageUtility and ResourceLibrary, you can easily pull a PNG out of a standard, non-.net resource library/dll:
public static Bitmap GetStandardResourceBitmap(String dllName, String resourceId) {
Bitmap result = null;
using (ResourceLibrary library = new ResourceLibrary() { Filename = dllName }) {
IntPtr hDib = library.GetResource(resourceId, ResourceLibrary.ImageType.IMAGE_BITMAP, ResourceLibrary.ImageLoadOptions.LR_CREATEDIBSECTION);
if (!hDib.Equals(IntPtr.Zero)) {
result = ImageUtility.DibToBitmap(hDib);
ImageUtility.DeleteObject(hDib);
}
}
return result;
}
I chose to have resourceId in my method a String, only because it doesn't require an overload and using numbered resource Ids is as simple as prepending a '#'.
GetStandardResourceBitmap("shell32.dll", "#632");
Cheers
A PNG image is not one of the standard Win32 resource types. It is usually embedded as a binary blob with the named resource type "PNG", although that's not guaranteed. By far the easiest way to figure this out is by opening the file with Visual Studio's File + Open + File command. You'll see the embedded resources organized in a tree, hopefully with a descriptive name, right-click a candidate and select Export to save it to disk.
Doing this programmatically requires a lot of gritty pinvoke. It is tricky because both the resource type and the resource ID can be either a string or an IntPtr so you'll need 4 overloads for FindResource. In order, you'll need LoadLibraryEx() to load the file without executing any of its code. FindResource to get a handle to the resource. SizeOfResource to know how large it is. LoadResource + LockResource to get a pointer to the resource data. Marshal.Copy() to copy the resource data into a byte[]. Clean up with FreeResource and FreeLibrary.