I am working on Enterprise Architect through C# add-ins. I need to display the image manager through automation where user can add directly add images on an "add image" button click in form.
I use the API Repository.InvokeConstructPicker() but it only opens the select package/class/component window. Is there an EA API available to open the Image Manager.
No, there is none. There is the undocumented Respository.CustomCommand which can open several properties windows. But the image manager is not part of that (or it has not been discovered what parameters to supply).
Please see Edit2 below about adding new values to the table.
Edit: Based on another question I had to dig into this a bit deeper.
I found out that, although EA imports a number of different image formats, it internally uses PNG to store the image. Obviously their BMP-importer does not like all BMP formats (not so deep in that, but I seem to remember there's some 8/16 bit stuff; typical Windoze weirdness). Anyhow, I used this Python code snippet to retrieve some test image data, previously imported into EA:
import sys
import win32com.client
import base64
import xml.etree.ElementTree
eaRep = None
try:
eaApp = win32com.client.GetActiveObject(Class="EA.App")
eaRep = eaApp.repository
except:
print "failure to open EA"
sys.exit(2)
def dump():
sqlRes = eaRep.SQLQuery("SELECT * FROM t_image")
root = xml.etree.ElementTree.fromstring(sqlRes)
for dataset in root:
for data in dataset:
for row in data:
name = row[1].text
print name
data = row[3].text
png = base64.standard_b64decode(data)
file = open("c:/" + name + ".png", "wb")
file.write(png)
file.close()
dump()
This correctly extracted the images from the database.
Edit2: I was assuming that EA stores the png as base64, but that's not true. EA only delivers base64 on return of SQLQuery. But they internally just store the raw png in Image. So, unfortunately, you can not use Repository.Execute since it can not transport binary data - or at least I have not figured out how to do that. As a work around you can look into Repository.ConnectionString and open a native connection to the database. Once you have plugged the new picture(s) in the table you can use them via thier ImageID.
Contents of t_image:
ImageID : You just need to create an unique ID
Name : an arbitrary string
Type : fixed string Bitmap
Image : blob of a png
Here's a Python snippet that connects natively to an EAP file:
import pyodbc
db_file = r'''C:\Documents and Settings\Administrator\Desktop\empty.eap'''
odbc_conn_str = 'DRIVER={Microsoft Access Driver (*.mdb)};DBQ=' + db_file
conn = pyodbc.connect(odbc_conn_str)
cursor = conn.cursor()
cursor.execute("select * from t_image")
row = cursor.fetchone()
if row:
print(row)
Rather than printing the row with the image data (which shows that its contents is a png-blob) you can use it to actually issue an INSERT or UPDATE to modify t_image.
Related
In PowerApps, let's say I have a field of "image" type called foo_imagefield on a table foo_testtable. I want to access the full size of this image in a plugin or console app using IOrganizationService. I can retrieve the record with the image field as follows:
string[] columns = { "foo_imagefield" };
Entity testRecord = Service.Retrieve("foo_testtable", new Guid("4B365AFD-B31C-EC11-B6E6-000D3A4EA781"), new ColumnSet(columns));
Now I can get the image bytes from the field:
byte[] imageBytes = testRecord.GetAttributeValue<byte[]>("foo_imagefield");
Great, except this only seems to give me the thumbnail version of the image (I believe PowerApps reduces it to 144px * 144px). It's super tiny. I know I can get the full version via a URL (e.g. https://myinstance.crm.dynamics.com/Image/download.aspx?Entity=foo_testtable&Attribute=foo_imagefield&Id=4b365afd-b31c-ec11-b6e6-000d3a4ea781&Timestamp=637801267356898020&Full=true as long as you are authenticated). I can also get the full version via rest API (e.g. GET /api/data/v9.1/<entity-type(id)>/<image-attribute-name>/$value?size=full). But being that I'm doing this in a plugin, I don't want to have to authenticate again.
Is there any way to get the full image with Microsoft.CRM.SDK IOrganizationService?
I am trying to build a PowerPoint add-in that will allow me to do a one-click optimization of the current presentation by removing unused master slides and converting huge 24-bit PNG files to slightly-compressed JPGs.
I have the first part handled already, and now I'm working on the images. Although I can easily find the Shape object containing the image, I cannot find a way to access the source image through the managed API. At best, I can copy the shape to the clipboard, which does give me the image but in a different format (MemoryBmp).
using PPTX = Microsoft.Office.Interop.PowerPoint;
...
foreach (PPTX.Slide slide in Globals.ThisAddIn.Application.ActivePresentation.Slides)
{
foreach (PPTX.Shape shape in slide.Shapes)
{
if (shape.Type == MsoShapeType.msoPicture)
{
// Now, how can I access the source image contained within this shape?
// I -can- copy it via the clipboard, like this:
shape.Copy();
System.Drawing.Image image = Clipboard.GetImage();
// ...but image's format reflects a MemoryBmp ImageFormat, as noted here:
// https://referencesource.microsoft.com/#System.Drawing/commonui/System/Drawing/Advanced/ImageFormat.cs
// ...which doesn't help me determine if the source image is something that should be optimized.
}
}
}
Obviously, I can get to the images directly via other methods (e.g. accessing the contents of the file as a ZIP, or using OpenXML SDK), but I'm trying to perform all the steps from within the already-opened presentation (which means I can't update the open file). Any thoughts on how I can do this?
You could use a Microsoft.Office.Interop.PowerPoint.Shape Export function.
void Export(string PathName, PpShapeFormat Filter, int ScaleWidth = 0, int ScaleHeight = 0, PpExportMode ExportMode = PpExportMode.ppRelativeToSlide)
There is a very little documentation of this function.
I've found it in the Shape interface definition.
So your code would look something like:
shape.Export(<some_file>, PpShapeFormat.ppShapeFormatPNG);
More info on MSDN
Is there an API to use Onenote OCR capabilities to recognise text in images automatically?
If you have OneNote client on the same machine as your program will execute you can create a page in OneNote and insert the image through the COM API. Then you can read the page in XML format which will include the OCR'ed text.
You want to use
Application.CreateNewPage to create a page
Application.UpdatePageContent to insert the image
Application.GetPageContent to read the page content and look for OCRData and OCRText elements in the XML.
OneNote COM API is documented here: http://msdn.microsoft.com/en-us/library/office/jj680120(v=office.15).aspx
When you put an image on a page in OneNote through the API, any images will automatically be OCR'd. The user will then be able to search any text in the images in OneNote. However, you cannot pull the image back and read the OCR'd text at this point.
If this is a feature that interests you, I invite you to go to our UserVoice site and submit this idea: http://onenote.uservoice.com/forums/245490-onenote-developers
update: vote on the idea: https://onenote.uservoice.com/forums/245490-onenote-developer-apis/suggestions/10671321-make-ocr-available-in-the-c-api
-- James
There is a really good sample of how to do this here:
http://www.journeyofcode.com/free-easy-ocr-c-using-onenote/
The main bit of code is:
private string RecognizeIntern(Image image)
{
this._page.Reload();
this._page.Clear();
this._page.AddImage(image);
this._page.Save();
int total = 0;
do
{
Thread.Sleep(PollInterval);
this._page.Reload();
string result = this._page.ReadOcrText();
if (result != null)
return result;
} while (total++ < PollAttempts);
return null;
}
As I will be deleting my blog (which was mentioned in another post), I thought I should add the content here for future reference:
Usage
Let's start by taking a look on how to use the component: The class OnenoteOcrEngine implements the core functionality and implements the interface IOcrEngine which provides a single method:
public interface IOcrEngine
{
string Recognize(Image image);
}
Excluding any error handling, it can be used in a way similar to the following one:
using (var ocrEngine = new OnenoteOcrEngine())
using (var image = Image.FromFile(imagePath))
{
var text = ocrEngine.Recognize(image);
if (text == null)
Console.WriteLine("nothing recognized");
else
Console.WriteLine("Recognized: " + text);
}
Implementation
The implementation is far less straight-forward. Prior to Office 2010, Microsoft Office Document Imaging (MODI) was available for OCR. Unfortunately, this no longer is the case. Further research confirmed that OneNote's OCR functionality is not directly exposed in form of an API, but the suggestions were made to manually parse OneNote documents for the text (see Is it possible to do OCR on a Tiff image using the OneNote interop API? or need a document to extract text from image using onenote Interop?. And that's exactly what I did:
Connect to OneNote using COM interop
Create a temporary page containing the image to process
Show the temporary page (important because OneNote won't perform the OCR otherwise)
Poll for an OCRData tag containing an OCRText tag in the XML code of the page.
Delete the temporary page
Challenges included the parsing of the XML code for which I decided to use LINQ to XML. For example, inserting the image was done using the following code:
private XElement CreateImageTag(Image image)
{
var img = new XElement(XName.Get("Image", OneNoteNamespace));
var data = new XElement(XName.Get("Data", OneNoteNamespace));
data.Value = this.ToBase64(image);
img.Add(data);
return img;
}
private string ToBase64(Image image)
{
using (var memoryStream = new MemoryStream())
{
image.Save(memoryStream, ImageFormat.Png);
var binary = memoryStream.ToArray();
return Convert.ToBase64String(binary);
}
}
Note the usage of XName.Get("Image", OneNoteNamespace) (where OneNoteNamespace is the constant "http://schemas.microsoft.com/office/onenote/2013/onenote" ) for creating the element with the correct namespace and the method ToBase64 which serializes an GDI-image from memory into the Base64 format. Unfortunately, polling (See What is wrong with polling? for a discussion of the topic) in combination with a timeout is necessary to determine whether the detection process has completed successfully:
int total = 0;
do
{
Thread.Sleep(PollInterval);
this._page.Reload();
string result = this._page.ReadOcrText();
if (result != null)
return result;
} while (total++ < PollAttempts);
Results
The results are not perfect. Considering the quality of the images, however, they are more than satisfactory in my opinion. I could successfully use the component in my project. One issue remains which is very annoying: Sometimes, OneNote crashes during the process. Most of the times, a simple restart will fix this issue, but trying to recognise text from some images reproducibly crashes OneNote.
Code / Download
Check out the code at GitHub
not sure about OCR, but the documentation site for onenote API is this
http://msdn.microsoft.com/en-us/library/office/dn575425.aspx#sectionSection1
I have c# dynamic aspx page after new property add I create for record brochure
http://veneristurkey.com/admin/Brochure.aspx?Admin=PropertiesBrochureA4&id=36
but I want to this convert image file I am searching on internet but all with webbrowser and windows forms. I need on page load show not css type also image file. jpg, png or tiff how i can do this. i need to see sample code..
saving aspx page into an image 2
As I mentioned in my comment, your best bet is to opt for attempting to render HTML to an image.
Here is the link for a library that will allow your to render html to an image:
http://htmlrenderer.codeplex.com/
Here is code that does exactly what you're asking:
http://amoghnatu.wordpress.com/2013/05/13/converting-html-text-to-image-using-c/
Now all you have left is to get the html, since I'm assuming you don't want this to render to the browser prior to generating this image - you should look into grabbing the rendered html from the aspx page on the server prior to returning it, and then just return the image. To render a page:
https://stackoverflow.com/a/647866/1017882
Sorted.
If you do not mind using a commandline tool you can have a look at wkhtmltopdf. The package include a wkhtmltoimage component that can be used to convert HTML to image, using
wkhtmltoimage [URL] [Image Path]
Codaxy also wrote a wkhtmltopdf c# wrapper available through the NuGet package manager. I'm not sure if the wkhtmltoimage component was included, but it should be easy enough to figure out how they wrap the wkhtml components.
i fixed my problem with screenshot machine API they are my code..
public void resimyap()
{
var procad = WS.Satiliklars.Where(v => v.ForSaleID == int.Parse(Request.QueryString["id"])).FirstOrDefault();
var imageBytes = GetBytesFromUrl("http://api.screenshotmachine.com/?key=xxxxxx&size=F&url=http://xxxxxxx.com/a4.aspx?id=" + procad.ForSaleID);
string root = Server.MapPath("~/");
// clean up the path
if (!root.EndsWith(#"\"))
root += #"\";
// make a folder to store the images in
string fileDirectory = root + #"\images\a4en\";
// create the folder if it does not exist
if (!System.IO.Directory.Exists(fileDirectory))
System.IO.Directory.CreateDirectory(fileDirectory);
WriteBytesToFile( fileDirectory + + procad.ForSaleID + ".png", imageBytes);
Yes i also try wkhtmltopdf c# wrapper but in pdf or image converting time my computer fan goin crayz. also i must upload server exe file and my hosting firm didnt support them
I export data from my database to word in HTML format from my web application, which works fine for me , i have inserted image into record,
the document displays the image also , all works fine for me except when i save that file and send to someone else .. ms word will not find link to that image
Is there anyway to save that image on the document so path issues will not raise
Here is my code : StrTitle contains all the HTML including Image links as well
string strBody = "<html>" +
"<body>" + strTitle +
"</body>" +
"</html>";
string fileName = "Policies.doc";
//object missing = System.Reflection.Missing.Value;
// You can add whatever you want to add as the HTML and it will be generated as Ms Word docs
Response.AppendHeader("Content-Type", "application/msword");
Response.AppendHeader("Content-disposition", "attachment; filename=" + fileName);
Response.Write(strBody);
You can create your html img tag with the image data encoded with base64. This way the image data is contained in the html document it self.
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIA..." />
You images are probably only available via filesystem (i.e. their src starts with file).
There are a few ways
Make the image available via the internet: make sure their src starts with http and that they are hosted on a web server visible to the downloader (for example, the same server from which they are dowonloading the image)
Use a library, for example see NuGet
You can inline the images as #DevZer0 suggests.
Based on experience
Is the simplest to implement but has some annoyances (the server needs to be available to the user)
Is probably the best way if you do a lot of Word or Office files manipulation.
Can be done and it would solve the problem, although you wouldn't have a full library to support further use cases.
Use a word document creation library if you really want to have flexibility in creating doc or docx type files. Like all other popular document formats, the structure needs to be accurate enough for the program that opens up the documents. Like you obviously cannot create a PDF file just by setting content type "application/PDF", if your content is not in a structure that PDF reader expects. Content type would just make the browser identify the extension (incorrectly in this case) and download it as a PDF, but its actually simple text. Same goes for MS word or any other format that requires a particular document structure to be parsed and displyed properly.
Since every picture, table is of type shape in Word/Excel/Powerpoint, you could simply add with your program an AlternativeText to your picture, which would actually save a URL of the download URL and when you open, it will retrieve its URL and replace it.
foreach (NetOffice.WordApi.InlineShape s in docWord.InlineShapes)
{
if (s.Type==NetOffice.WordApi.Enums.WdInlineShapeType.wdInlineShapePicture && s.AlternativeText.Contains("|"))
{
s.AlternativeText=<your website URL to download the picture>;
}
}
This would be the C# approach, but would require more time for the picture. If you write a small software for it, which replaces all pictures which contain a s.AlternativeText, you could replace a lot of pictures at same time.
NetOffice.WordApi.InlineShape i=appWord.ActiveDocument.InlineShapes.AddPicture(s.AlternativeText, false, true);
It will look for the picture at that location.
You can do that for your whole document with the 1 loop I wrote you. Means, if it is a picture and contains some AlternativeText, then inside you loop you use the AddPicture function.
Edit: Anoter solution, would be to set a hyperlink to your picture, which would actually go to a FTP server where the picture is located and when you click on the picture, it will open it, means he can replace it by himself(bad, if you have 200 pictures in your document)
Edit according Clipboard:
string html = Clipboard.GetText(TextDataFormat.Html);
File.WriteAllText(temporaryFilePath, html);
NetOffice.WordApi.InlineShape i=appWord.ActiveDocument.InlineShapes.AddPicture(temporaryFilePath, false, true);
The Clipboard in Word is capable to transform a given HTML and when you paste it to transform that table or picture into Word. This works too for Excel, but doesn't for Powerpoint. You could do something like that for your pictures and drag and drop from your database.