The C# code below should produce an EMF, but viewing the output (in Vim) shows it to be a PNG. Perhaps someone on S.O. knows a good work-around or solution.
MathKernel k = new MathKernel();
k.CaptureGraphics = true;
k.GraphicsFormat = "Metafile";
k.Compute("Show[Graphics[{Thick, Blue, Circle[{#, 0}] & /# Range[4], Black, Dashed, Line[{{0, 0}, {5, 0}}]}]]");
k.Graphics[0].Save("C:\\Temp\\file.emf", System.Drawing.Imaging.ImageFormat.Emf);
So far I'm considering wrapping Show[Graphics...] in ExportString[... , "EMF"] and collecting the result using the MathKernel Result property.
Addendum
The MathKernel.Graphics property[1] is apparently a .Net Graphics method which only handles image files such as bitmaps, not vector graphic based enhanced metafiles.
http://reference.wolfram.com/legacy/v7/NETLink/ref/net/Wolfram.NETLink.MathKernel.Graphics.html
Enhanced metafiles can be transferred through .NETLink one at a time though, in the following manner:
using System;
using System.IO;
using Wolfram.NETLink;
public class Example
{
public static void Main(String[] args)
{
MathKernel k = new MathKernel();
k.Compute("ExportString[Graphics[{Disk[]}], {\"Base64\", \"EMF\"}]");
byte[] decodedBytes = Convert.FromBase64String(k.Result.ToString());
// The transferred EMF can be used or simply written out to file.
File.WriteAllBytes("C:\\Temp\\file.emf", decodedBytes);
}
}
Here is a working solution:
using System;
using Wolfram.NETLink;
public class Example {
public static void Main(String[] args) {
MathKernel k = new MathKernel();
k.Compute("Export[\"c:/users/arnoudb/out.emf\", Graphics[{Disk[]}], \"EMF\"]");
}
}
I am not sure why you consider this part:
k.Graphics[0].Save("C:\\Temp\\file.emf", System.Drawing.Imaging.ImageFormat.Emf);
a Mathematica bug, since k.Graphics[0] is a pure C# System.Drawing.Image class. Perhaps you can clarify this part a bit?
Related
Ok, so this is what's going on. I'm trying to learn how to use vscode (switching over from jgrasp). I'm trying to run this old school assignment that requires the use of outside .txt files. The .txt files, as well as other classes that I have written are in the same folder and everything. When I try to run this program in JGrasp, it works fine. Though, in VSCode, I get an exception. Not sure what is going wrong here. Thanks Here is an example:
import java.io.*;
public class HangmanMain {
public static final String DICTIONARY_FILE = "dictionary.txt";
public static final boolean SHOW_COUNT = true; // show # of choices left
public static void main(String[] args) throws FileNotFoundException {
System.out.println("Welcome to the cse143 hangman game.");
System.out.println();
// open the dictionary file and read dictionary into an ArrayList
Scanner input = new Scanner(new File(DICTIONARY_FILE));
List<String> dictionary = new ArrayList<String>();
while (input.hasNext()) {
dictionary.add(input.next().toLowerCase());
}
// set basic parameters
Scanner console = new Scanner(System.in);
System.out.print("What length word do you want to use? ");
int length = console.nextInt();
System.out.print("How many wrong answers allowed? ");
int max = console.nextInt();
System.out.println();
//The rest of the program is not shown. This was included just so you guys could see a little bit of it.
If you're not using a project, jGRASP makes the working directory for your program the same one that contains the source file. You are creating the file with a relative path, so it is assumed to be in the working directory. You can print new File(DICTIONARY_FILE).getAbsolutePath() to see where VSCode is looking (probably a separate "classes" directory) and move your data file there, or use an absolute path.
I am trying to programically determine if a video card is set to "maintain aspect ratio". I've tracked down this registry key in windows.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GraphicsDrivers\Configuration\\00\00
scaling =
4 = maintain aspect ratio 3 = scale full screen 2 = center image
This would be great, but it appears that "maintain display scaling" will retain whatever that key was set to before.
Does anyone have another location or another method to confirm, that a video card is set to maintain aspect ratio? (not using a cards GUI)
I should clarify this isn't about DPI settings, this is about aspect ratio of the video being displayed.
Posting this as an answer (even though it's not) since I need to space to show what I've done so far--in case it helps anyone towards the answer. I'm currently looking through other Windows API libs to try and find the answer.
#MinerBob, I saw that guy's code yesterday too but couldn't get it to work so I changed a few things and am now reporting the data as correctly as I can but looking over the struct, it doesn't appear to contain the information you're after but here's how you can generate the output to review it yourself:
Add-Type "
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Forms;
[StructLayout(LayoutKind.Sequential)]
public struct DEVMODE
{
private const int CCHDEVICENAME = 0x20;
private const int CCHFORMNAME = 0x20;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public int dmFields;
public int dmPositionX;
public int dmPositionY;
public ScreenOrientation dmDisplayOrientation;
public int dmDisplayFixedOutput;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string dmFormName;
public short dmLogPixels;
public int dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmDisplayFlags;
public int dmDisplayFrequency;
public int dmICMMethod;
public int dmICMIntent;
public int dmMediaType;
public int dmDitherType;
public int dmReserved1;
public int dmReserved2;
public int dmPanningWidth;
public int dmPanningHeight;
}
public static class user32
{
[DllImport(`"user32.dll`")]
public static extern bool EnumDisplaySettings(string lpszDeviceName, int iModeNum, ref DEVMODE lpDevMode);
public const int ENUM_CURRENT_SETTINGS = -1;
public const int ENUM_REGISTRY_SETTINGS = -2;
public static void GetDisplaySettings()
{
DEVMODE vDevMode = new DEVMODE();
if (EnumDisplaySettings(null, ENUM_CURRENT_SETTINGS, ref vDevMode))
{
Console.WriteLine(#`"
dmDeviceName = {0}
dmSpecVersion = {1}
dmDriverVersion = {2}
dmSize = {3}
dmDriverExtra = {4}
dmFields = {5}
dmPositionX = {6}
dmPositionY = {7}
dmDisplayOrientation = {8}
dmDisplayFixedOutput = {9}
dmColor = {10}
dmDuplex = {11}
dmYResolution = {12}
dmTTOption = {13}
dmCollate = {14}
dmFormName = {15}
dmLogPixels = {16}
dmBitsPerPel = {17}
dmPelsWidth = {18}
dmPelsHeight = {19}
dmDisplayFlags = {20}
dmDisplayFrequency = {21}
dmICMMethod = {22}
dmICMIntent = {23}
dmMediaType = {24}
dmDitherType = {25}
dmReserved1 = {26}
dmReserved2 = {27}
dmPanningWidth = {28}
dmPanningHeight = {29}
`",
vDevMode.dmDeviceName,
vDevMode.dmSpecVersion,
vDevMode.dmDriverVersion,
vDevMode.dmSize,
vDevMode.dmDriverExtra,
vDevMode.dmFields,
vDevMode.dmPositionX,
vDevMode.dmPositionY,
vDevMode.dmDisplayOrientation,
vDevMode.dmDisplayFixedOutput,
vDevMode.dmColor,
vDevMode.dmDuplex,
vDevMode.dmYResolution,
vDevMode.dmTTOption,
vDevMode.dmCollate,
vDevMode.dmFormName,
vDevMode.dmLogPixels,
vDevMode.dmBitsPerPel,
vDevMode.dmPelsWidth,
vDevMode.dmPelsHeight,
vDevMode.dmDisplayFlags,
vDevMode.dmDisplayFrequency,
vDevMode.dmICMMethod,
vDevMode.dmICMIntent,
vDevMode.dmMediaType,
vDevMode.dmDitherType,
vDevMode.dmReserved1,
vDevMode.dmReserved2,
vDevMode.dmPanningWidth,
vDevMode.dmPanningHeight
);
}
}
}
" -ReferencedAssemblies System.Windows.Forms
[user32]::GetDisplaySettings()
UPDATE 1:
According to the MSDN documentation for EnumDisplaySettings:
The EnumDisplaySettings function sets values for the following five
DEVMODE members:
dmBitsPerPel
dmPelsWidth
dmPelsHeight
dmDisplayFlags
dmDisplayFrequency
what I was originally focusing on 'dmScale' appears to be specific to Printers--as in, only Printer functions that populate the DEVMODE struct will fill that field.
Update 2:
It appears everything under GraphicsDrivers key, well, is updated by the graphics driver that's loaded for that monitor. Very Intuitive. Every article I could find talks about either changing the value in the vendor-specific UI that interacts with its driver OR using the appropriate monitor key under Graphics Drivers to interact with this feature.
There must be some Windows Graphics Driver documentation that talks about each driver updating/honoring these values. Looking for that now to confirm.
Update 3:
Updated source to include the DEVMODE structure signature from pinvoke.net. Also, I believe I found the smoking gun in Windows driver documentation:
Scaling depends on the source and target modes that are used for a
path. In addition, the caller can call SetDisplayConfig without
specifying the target mode information (that is, setting the
modeInfoArray parameter is optional and can be set to NULL).
Therefore, the caller cannot typically predict if SetDisplayConfig
must perform any scaling. Furthermore, no API exists to get the full
list of scaling types that the graphics adapter supports. The
EnumDisplaySettings Win32 function (described in the Windows SDK
documentation) returns DMDFO_DEFAULT in the dmDisplayFixedOutput
member of the DEVMODE structure that the lpDevMode parameter points to
when the caller requests the new Windows 7 scaling types.
The scaling that a caller passes to SetDisplayConfig is a scaling
intent rather than an explicit request to perform a scaling operation.
If scaling is required (for example, source and target resolutions
differ), SetDisplayConfig uses the scaling that the caller supplies.
If the supplied scaling is not supported, SetDisplayConfig uses the
graphics adapter's default scaling. When the source and target
resolutions that the caller passes to SetDisplayConfig are the same,
SetDisplayConfig always sets identify scaling.
...my bolded emphasis. DMDFO_DEFAULT, according to the header file, is 0.
Sources:
https://learn.microsoft.com/en-us/windows-hardware/drivers/display/scaling-the-desktop-image
https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-devmodea
I have currently developed an ultimately open source application to analyse some data in a table view and visualise the resulting data in some additional plots. A problematic thing with this is, that the generated plots could potentially be useful for end users for e.g. a presentation, further downstream informative discussion and so on. This is why I started working on an export function using ImageWriter
//adding a context menu item to the chart
final MenuItem saveAsPng = new MenuItem("Save as png");
saveAsPng.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent event) {
int scale = 6; //6x resolution should be enough, users should downscale if required
final Bounds bounds = bc.getLayoutBounds();
final SnapshotParameters spa = new SnapshotParameters();
spa.setTransform(javafx.scene.transform.Transform.scale(scale, scale));
ImageWriter imageWriter = new ImageWriter();
try {
imageWriter.saveImage(stage, bc.snapshot(spa, null));
} catch (ImageException e) {
e.printStackTrace();
}
}
});
This successfully creates a PNG file with sufficient size, but my ideal solution would be to export in vector-based format, e.g. PDF/SVG. For Swing applications, I knew how to achieve this, but for JFX I couldn't really find a proper solution for that matter. I already investigated several potential ideas, e.g. using a printer dialogue and then exporting as a PDF via virtual printer, but that does result in a bitmap inside the PDF, too.
Any ideas on this?
Guys Im using the following custom code to load 20 images from resources and present in a viewpager
public class CustomPagerAdapter extends PagerAdapter {
int[] mResources = {
R.drawable.slide1,
R.drawable.slide2,
R.drawable.slide3,
R.drawable.slide4,
R.drawable.slide5,
R.drawable.slide6,
R.drawable.slide7,
R.drawable.slide8,
R.drawable.slide9,
R.drawable.slide10,
R.drawable.slide11,
R.drawable.slide12,
R.drawable.slide13,
R.drawable.slide14,
R.drawable.slide15,
R.drawable.slide16,
R.drawable.slide17,
R.drawable.slide18,
R.drawable.slide19,
R.drawable.slide20,
};
Context mContext;
LayoutInflater mLayoutInflater;
public CustomPagerAdapter(Context context) {
mContext = context;
mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return mResources.length;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((LinearLayout) object);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
View itemView = mLayoutInflater.inflate(R.layout.pager_item, container, false);
ImageView imageView = (ImageView) itemView.findViewById(R.id.imageView);
imageView.setImageResource(mResources[position]);
container.addView(itemView);
return itemView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((LinearLayout) object);
}
}
This works fine but I want to put the jpgs in a directory on the device so that they can be changed without recompiling the app
I think I need to get the images into the mResource array. I can get the path but not sure what format the code should be instead of using the draw-able lines
i have read articles on here but none make sense to me I am really new to this and the code looks nothing like the code I am using
can anyone point me in the right direction?
Any help is greatly appreciated
Mark
Yes, you can certainly do so. I will try to explain you the process step-by-step,
Step 1
Have a File object pointing to the path, like,
File directory = new File("path-to-directory");
Ensure that the path is to the directory with the images,
Step 2
List all the files inside the directory using listFiles() method, like
File[] allImages = directory.listFiles();
Now you have an array of all the files just like int[] mResources. The only difference being, now you have actual file references, while previously you had resource ids.
Step 3
You can just display the images in the ViewPager just like you did previously. But this is a bit tricky and can take you a considerable amount of time and code to get an image properly displayed from File.
You also need to take care of caching, so that when you load a previously loaded image again, it gets it from the cache.
To do all this, I recommend you to use this library (recommended by Google), Glide.
Setting an image is one line of code,
Glide.with(context).from(file).into(imageView);
That's it. Now you have your images displayed in a ViewPager from a directory in the device.
When debugging in IDE, how does the IDE know how to calculate the watch value without changing the environment (writing to file, writing result to DB)?
Your observation cannot be generalized. An IDE typically makes changes during debugging, especially if a property has a side effect.
Visual Studio
The following C# code:
using System;
namespace EvaluateChangesValue
{
class Program
{
static void Main()
{
var program = new Program();
Console.WriteLine(program.Value);
Console.ReadLine();
Console.WriteLine(program.Value);
Console.ReadLine();
}
private int member;
private int Value => member++;
}
}
Set a breakpoint at the first ReadLine(), then add program.Value to the watch window and see how the value gets increased due to the member++ statement.
Eclipse
In Java and Eclipse, it's a bit harder to make the same proof because for these reasons:
In Java it's more clear whether you call a method or access a field.
You need the "Expressions" window, which is not available by default
Re-evaluation needs user interaction
The code is similar to C#:
public class Program {
public static void main(String[] args)
{
Program p = new Program();
System.out.println(p.member);
System.console().readLine();
System.out.println(p.member);
System.console().readLine();
}
private int member;
public int getMember()
{
return member++;
}
}
And the screenshot: