Generate image for background in Batik - svg

I have a method that generates an array of bytes, which can be represented as a two dimensional image. I would like to show this image as a background image in batik. I do not want to save the array to disk (as image) and then load it into batik. Instead I would like to provide the array to the batik. I though that using ParsedURLData can help me, but I can not figure out how to make it work. Any suggestions?
I call ParsedURL.registerHandler(new MyProtocolHanlder("myprotocol")); and MyProtocolHanlder.parseURL returns MyParsedURLData.
I thought that returning my own stream would work, but it does not. In the example bellow I simply load an image from disk and try to display it.
class MyParsedURLData extends ParsedURLData {
public MyParsedURLData() {
}
#Override
public InputStream openStreamRaw(String arg0, Iterator arg1) throws IOException {
return new File("some_image_here").toURI().toURL().openStream();
}
}
If in the constructor for MyParsedURLData I set protocol = "file" and path="another_image", then another image will be loaded, no matter what stream is returned by openStreamRaw.
Any suggestions?

The simplest way is to save the image to a temp file, then just reference it via File.toURI().toURL(), and Batik will load it. You don't need a custom protocol handler or ParsedURL for this. Choose a standard image format supported by Batik such as PNG or JPEG for the temp file!
You can save the temp file by implementing both a ParsedURLProtocolHandler and a RegistryEntry and register them with Batik. There is a little bit of documentation on that on the web site, but it is still a pain to do. Took me some hours to figure out (and the code is not really ready for sharing), but I can now pass a BufferedImage directly to Batik without encoding it as a .png or similar file first.

Related

How do I use SharePlusLinuxPlugin?

I'm trying to open an image from memory with the default image viewer on Linux.
The class is part of the share_plus package. I can't figure out how to define the required UrlLauncherPlatform property.
I want to use it like this:
SharePlusLinuxPlugin(urlLauncher).shareXFiles([XFile.fromData(img)]);
I have googled this class, didn't find any usage examples.
From the source code on Github, it looks like shareXFiles() has not been implemented on Linux. To quote:
Future<ShareResult> shareXFiles(
List<XFile> files, {
String? subject,
String? text,
Rect? sharePositionOrigin,
}) {
throw UnimplementedError(
'shareXFiles() has not been implemented on Linux.',
);
}
The same is true for the shareFiles() method.
Aside from that, there is usually no need to call SharePlusLinuxPlugin directly. The Share class is configured in such a way that it automatically detects the platform that it is running on

How to load an svg to CanvasVirtualControl in C++/winrt?

I've been loading drawing svg images successfully in a UWP app built with C++/winrt but in the latest release find that the call to load the svg throws an exception.
The crash happens in an IAsync method that is hard to trace, but I've narrowed the problem down to the one line that loads the SVG.
This is normally looping to read lots of files, but very simple reduction of the problem still displays the issue:
winrt::Microsoft::Graphics::Canvas::UI::Xaml::CanvasVirtualControl resourceCreator
winrt::Windows::Storage::StorageFile nextFile = nullptr;
winrt::Microsoft::Graphics::Canvas::Svg::CanvasSvgDocument nextSvg = nullptr;
winrt::Windows::Storage::Streams::IRandomAccessStream fileStream = nullptr;
//This is called from within the lambda handling CreateResources for the CanvasVirtualControl
//The VirtualControl is provided as the resourceCreator argument
IAsyncAction loadSVGs(winrt::Microsoft::Graphics::Canvas::UI::Xaml::CanvasVirtualControl resourceCreator)
{
nextFile = m_symbol_resource_files.GetAt(i);
fileStream = co_await nextFile.OpenReadAsync();
nextSvg = co_await CanvasSvgDocument::LoadAsync(resourceCreator,fileStream);
}
The call to LoadAsync fails with
exception: winrt:hresult_invalid_argument at memory location 0x0C93F1CB
void resume()const{
->_coro_resume(_Ptr);
}
If I continue past the exception I find that the resource has in fact loaded and is usable. But if running outside Visual Studio the app will often quit at this line. Could it be that the CanvasVirtualControl is not acceptable?
Or is there a better way to load the svg from file? I haven't been able to work out the CanvasDocument's LoadFromXML, as it takes a System.String argument not available in C++/winrt and the winrt std::wstring is not acceptable as a substitute [Correction: in fact hstring will work as an argument and that can be created from std::wstring].
[Update]I have not yet created a simple demo project displaying this behavior, but I think I have a line on the cause and would like to extend my question. I've tried both the LoadFromXml and the LoadAsync methods of the CanvasSvgDocument, and the second of these used to be fine, but now both fail the same way and it seems to me that the ResourceCreator argument may be the trouble. I am creating these resources in the CreateResources handler and I pass the sender - CanvasVirtualControl - as the resourceCreator. The listed argument for both the CanvasSvgDocument calls, however, is ICanvasResourceCreator. I had thought this was a convenience and that the CanvasVirtualControl could be passed directly for that argument (and so it used to be). But perhaps this is incorrect, maybe always was and is now being noticed as incorrect? If so, how would the sender in the CreateResources handler properly be passed to the CanvasSvgDocument method?
I created a blank app to use CanvasVirtualControl to load SVG, it worked well. Can you provide a simple sample that can be reproduced? And I checked the LoadFromXML method, the parameter it needs is hstring type instead of System.String.
In addition, about loading the svg from file, do you have to use win2d to load svg? If not, you could try to use Image control by SvgImageSource to load svg, like below:
.xaml:
<Image x:Name="MyImage" Width="300" Height="200"></Image>
.cpp:
winrt::Windows::Storage::StorageFile nextFile = nullptr;
winrt::Microsoft::Graphics::Canvas::Svg::CanvasSvgDocument nextSvg = nullptr;
winrt::Windows::Storage::Streams::IRandomAccessStream fileStream = nullptr;
nextFile = co_await KnownFolders::PicturesLibrary().GetFileAsync(L"Freesample.svg");
fileStream = co_await nextFile.OpenReadAsync();
SvgImageSource sourcee = SvgImageSource();
co_await sourcee.SetSourceAsync(fileStream);
MyImage().Source(sourcee);

How to get FileInfo objects from the Orchard Media folder?

I'm trying to create a custom ImageFilter that requires me to temporarily write the image to disk, because I'm using a third party library that only takes FileInfo objects as parameters. I was hoping I could use IStorageProvider to easily write and get the file but I can't seem to find a way to either convert an IStorageFile to FileInfo or get the full path to the Media folder of the current tenant to retrieve the file myself.
public class CustomFilter: IImageFilterProvider {
public void ApplyFilter(FilterContext context)
{
if (context.Media.CanSeek)
{
context.Media.Seek(0, SeekOrigin.Begin);
}
// Save temporary image
var fileName = context.FilePath.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).LastOrDefault();
if (!string.IsNullOrEmpty(fileName))
{
var tempFilePath = string.Format("tmp/tmp_{0}", fileName);
_storageProvider.TrySaveStream(tempFilePath, context.Media);
IStorageFile temp = _storageProvider.GetFile(tempFilePath);
FileInfo tempFile = ???
// Do all kinds of things with the temporary file
// Convert back to Stream and pass along
context.Media = tempFile.OpenRead();
}
}
}
FileSystemStorageProvider does a ton of heavy lifting to construct paths to the Media folder so it's a shame that they aren't publicly accessible. I would prefer not to have to copy all of that initialization code. Is there an easy way to directly access files in the Media folder?
I'm not using multitenancy, so forgive me if this is inaccurate, but this is the method I use for retrieving the full storage path and then selecting FileInfo objects from that:
_storagePath = HostingEnvironment.IsHosted
? HostingEnvironment.MapPath("~/Media/") ?? ""
: Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Media");
files = Directory.GetFiles(_storagePath, "*", SearchOption.AllDirectories).AsEnumerable().Select(f => new FileInfo(f));
You can, of course, filter down the list of files using either Path.Combine with subfolder names, or a Where clause on that GetFiles call.
This is pretty much exactly what FileSystemStorageProvider uses, but I haven't had need of the other calls it makes outside of figuring out what _storagePath should be.
In short, yes, you will likely have to re-implement whatever private functions of FileSystemStorageProvider you need for the task. But you may not need all of them.
I was struggling with a similar issue too and i can say that the IStorageProvider stuff is pretty much restricted.
You can see this when viewing the code of FileSystemStorageFile. The class already uses FileInfo to return data but the struct itself isn't accessible and other code is based on this. Therefore you would have to basically reimplement everything from scratch (own implementation of IStorageProvider). The easiest option is to simply call
FileInfo fileInfo = new FileInfo(tempFilePath);
but this would break setups where no file system based storage provider is used like AzureBlobStorageProvider.
The proper way for this task would be to get your hands dirty and extend the storage provider interfaces and update all the code that is based on it. But as far as i can remember the issue here is that you need to update the Azure stuff also and then things get really messy. Due to this fact i aborted that approach when trying to do this heavy stuff on my project.

How to convert a emf image file into PNG format in Azure web app

I want to convert a emf image file into PNG format.It works in local machine. But while running it in azure does not give a correct output. It gives only blank image frame.What should I do?
According to your description and your profile, I suggest you could use System.Drawing.Image class to convert the emd to png.
I also created a test demo and publish it to the azure, it works well.
More details, you could refer to this codes:
protected void Button2_Click(object sender, EventArgs e)
{
System.Drawing.Image image1 = System.Drawing.Image.FromFile(Server.MapPath(#"/image/test.Emf"));
image1.Save(Server.MapPath(#"/image/test2.png"), System.Drawing.Imaging.ImageFormat.Png);
}
If you use another way and still face this issue, I suggest you could post more relevant codes for us to repro your issue.

Dimensions of ImageMarker

I am new to Vuforia SDK. I have an image which acts as a target. I want to place this image on to the Imagemarker. In real time the size of the Imagemarker varies. Is there any method where I can get the width and height of the Imagemarker so that the target image fits exactly on the Imagemarker?
Since you did not specify if you are using the Unity or native APIs I will assume you are using Unity.
This is how you would go about it using the Vuforia API, placing this in a script attached to your ImageTarget GameObject.
IEnumerator Start()
{
Vuforia.ImageTarget img = GetComponent<Vuforia.ImageTargetBehaviour>().ImageTarget;
// This is rounded of in the console display,
// so individual components are printed afterwards
Debug.Log(img.GetSize());
Debug.Log(img.GetSize().x);
Debug.Log(img.GetSize().y);
Debug.Log(img.GetSize().z);
}
Alternatively you can directly use the Bounds of the renderer.
void Start()
{
Renderer r = GetComponent<Renderer>();
Debug.Log(r.bounds.size.x);
Debug.Log(r.bounds.size.y);
Debug.Log(r.bounds.size.z);
}
Needless to say this is just a quick solution, depending on the situation you might want to use this at runtime dynamically create content.
Yes, you can.
While placing the Image on the Image Marker to the relative size you want it to be, and when you run it you'll see that the size of the image will be relative to the Marker you've placed it on.

Resources