I have a question. I'm new to ZPL language I used zebra designer to create a label in 200dpi. If I want to make the same label but in 300dpi. What does it change in my zpl code exactly? I was thinking of the dimension, like in
^LL799
799 will change to another size, but is there anything else?
EDIT:
My goal is to create a C# application to print label on my zebra printers.
The user will choose if it's a 200dpi or a 300dpi and then the right code is sent to GenericText/Only to print on my printer (print to GenericText/Only is required I can't change that). So if you know a way to do that in C# I take it too.
Thanks in advance
To switch resolution, the ZPL template needs to change in order for the label to be printed correctly. Basically it's just a matter of scaling by 3/2 for most fields. For example:
200dpi 300dpi
-------- --------
^FO40,40 -> ^FO60,60
^BY4 -> ^BY6
And so on. I coded a converted that does the opposite, just change the multiplier from 2/3 to 3/2 and you should be good to go:
public static void Main()
{
var evaluator = new MatchEvaluator(Converter);
const string pattern = #"(?<=\^[A-Z0-9]{2,3},?)([0-9]+,[0-9]+)";
const string input = #" ... ZPL CODE HERE";
Console.WriteLine(Regex.Replace(input, pattern, evaluator));
Console.WriteLine();
Console.WriteLine("Press any key to quit...");
Console.ReadKey();
}
public static string Converter(Match match)
{
var (w, h) = (double.Parse(match.Value.Split(',')[0]), double.Parse(match.Value.Split(',')[1]));
var (wNew, hNew) = ((int)Math.Floor(w * 2 / 3), (int)Math.Floor(h * 2 / 3));
return wNew + "," + hNew;
}
This will not convert some fields, such as barcodes. You need to change those manually. You should use http://labelary.com/viewer.html to check the results and adapt. Open 2 viewers and paste 203 and 300 dpi, then select the resolution and label size and compare.
Related
I have 4 buttons: button_1 writes in the InputBox the number 1, button_plus writes in the same Inputbox +, button_2 writes the number 2. Finally stands in the Inputbox: 1 + 2.
Now, I want to use the button_Equals, to get 1 + 2 from the Inputbox and assign them to a variable. I used int.Parse(), Int32.Parse() and Convert.ToInt32() to get both numbers 1 and 2:
r = int.Parse(textBox1.Text);
s = int.Parse(textBox1.Text);
I'd like to assign 1 to r and 2 to s, but the program collapses when I click on the Button_Equals and it shows the following message:
System.FormatException
Why do you write them to the input as text and then try to parse that text? It's much better and easier to assign them to variables while you're writing them to the input, and then use the values directly from the variables.
Anyway, if you really want to parse the text in the input, you've got to first remove the + sign and then split the two values. Something like this:
var x = textBox1.Text.Split('+');
s = int.Parse(x[0]);
r = int.Parse(x[1]);
I am looking for a way to figure out if textboxes are filled in in a specific way.
I have the following textboxes:
X1 Y1 Z1
X2 Y2 Z2
X3 Y3 Z3
Users are expected to input into them continuously. For example, if only X1,Y1 have texts, it's valid. While if X1,Z1 have texts while Y1 hasn't, it's invalid.
The reason for this is because:
string G1
if(!string.IsNullOrWhiteSpace(X1.Text) && string.IsNullOrWhiteSpace(Y1.Text))
{
G1 = "<" + X1.Text + ">";
}
else if(!string.IsNullOrWhiteSpace(X1.Text) && !string.IsNullOrWhiteSpace(Y1.Text))
{
G1 = "<" + X1.Text + ">, ";
}
If they skip around then what is printed in the end will not be what is expected.
If you can think of an easier way to do all of this, please share. I am sure that my way of attacking this problem is quite simplistic and inefficient.
The answer I found is to use an array of the text boxes, then to iterate over that to determine the text of the filled out boxes. Then add the text from those boxes to a list.
Finally I used joined all of the items of that list, in a way that made the final output correct.
Code I used in the end:
string[] cells = new string[] { X1.Text, Y1.Text, Z1.Text, X2.Text, Y2.Text, Z2.Text, X3.Text, Y3.Text, Z3.Text };
List<string> final_cells = new List<string>();
//Process array to determine which cells are full, adds full cells to list
for (int i = 0; i < cells.Length; i++)
{
if(cells[i].Length == 0)
{
//If cell is empty, continue to the next one
continue;
}
else
{
// If cell is full add its contents to the final_cells list
final_cells.Add(cells[i]);
}
}
//Join the list to one string
string content = string.Join(">, <", final_cells);
Also I am sorry that I did not better explain the original situation.
The purpose of the final application is to output text in a specific format for a minecraft plugin to read. The 3x3 of text boxes is meant to mimic the crafting grid from the game.
The type of recipe this part of the application is supposed to add does not need to use 9 items/blocks, and is not shaped (so it doesn't technically matter where the user inputs each item name). Because of this, the empty boxes have to be completely ignored, and the program needs to know if there is something coming next, so I could not simply say that the recipe ended at the first empty box.
An output of <item1> <item2> is not valid, the correct format is <item1>, <item2>. However the input can also be a single item... so this <only_item> is a valid format.
I hope it is clear both what the function of this is, but also why this was important for my application.
I have the following code to plot my input series using R charts from my C# application:
public void plotGraphR_2D(List<double> x, double[,] y)
{
string Rpath = #"C:\Program Files\R\R-3.1.0\bin\x64";
REngine.SetEnvironmentVariables(Rpath);
REngine engine = REngine.GetInstance();
var v1 = engine.CreateNumericVector(x);
var v2 = engine.CreateNumericMatrix(y);
if (engine.IsRunning == false)
{
engine.Initialize();
}
engine.SetSymbol("v1", v1);
engine.SetSymbol("v2", v2);
engine.Evaluate("require('ggplot2')");
engine.Evaluate("library('ggplot2')");
engine.Evaluate("my_data <- data.frame(v2)");
engine.Evaluate("colnames(my_data) <- c('Price', 'Quantity')");
engine.Evaluate("myChart <- ggplot() + geom_line(data = my_data, my_data$Price)"); // THIS DOESN'T WORK
engine.Evaluate("myChart");
//engine.Evaluate("plot(my_data$Price)"); // THIS WORKS
}
My input x is a list while y is a 2 dimensional array. I first convert x to numeric vector and y to data frame, then I change column names to the data frame.
I want to plot one of the column of my data frame (my_data$Price) but when using ggplot2 it doesn't work. I don't get any error but I don't see any chart popping up.
If I try using the last line engine.Evaluate("plot(my_data$Price)") (so normal plot) it works fine.
Is there any problem with the way I call ggplot2? I have installed the library with RStudio. Anything else I should do to fix the issue?
Thanks.
The R code provided does not work as it is reported. The code below does create a ggplot successfully, however the print statement creates a graphic device window but shows an incorrect display (blank form). So yes there is an issue, but I do not know exactly why. The only workaround I can suggest to try is to output images to disk.
engine.Evaluate("myChart <- ggplot(my_data, aes(x=Price, y=Quantity)) + geom_line()");
engine.Evaluate("print(myChart)");
Sorry for the weird title, I could't think of anything better!
Anyways, I'm half way through writing a program (Windows Forms App) that reads in a fixed-width file, gathers field lengths from user input, then it's supposed to display each column from the first line of the file in a different color... Do you know what I mean? It's basically to differentiate between the different fields in a fixed-width file using color.
What I wanted to ask was what was the best way to go about this? Because I'm having a lot of trouble, and I keep running into things and just implementing disgusting solutions when I know there is a much better one.
Obviously you don't have to give me a whole program, just some ideas of better ways to go about this - because my solution is just horrendous.
Thank you all in advance!
I would use a RichTextBox. This has an easy way to change the color of text. Here is an example where I have 3 inputs from the user that tells how wide each column should be. Then it reads in a file and colors the widths appropriately. Hopefully this will give you some more ideas.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
ReadFile();
}
private void ReadFile()
{
// Assumes there are 3 columns (and 3 input values from the user)
string[] lines_in_file = File.ReadAllLines(#"C:\Temp\FixedWidth.txt");
foreach (string line in lines_in_file)
{
int offset = 0;
int column_width = (int)ColumnWidth1NumericUpDown.Value;
// Set the color for the first column
richTextBox1.SelectionColor = Color.Khaki;
richTextBox1.AppendText(line.Substring(offset, column_width));
offset += column_width;
column_width = (int)ColumnWidth2NumericUpDown.Value;
// Set the color for the second column
richTextBox1.SelectionColor = Color.HotPink;
richTextBox1.AppendText(line.Substring(offset, column_width));
offset += column_width;
column_width = (int)ColumnWidth3NumericUpDown.Value;
// Make sure we dont try to substring incorrectly
column_width = (line.Length - offset < column_width) ?
line.Length - offset : column_width;
// Set the color for the third column
richTextBox1.SelectionColor = Color.MediumSeaGreen;
richTextBox1.AppendText(line.Substring(offset, column_width));
// Add newline
richTextBox1.AppendText(Environment.NewLine);
}
}
}
I'm gathering light statistics of EXIF data for a large collection of photos and I'm trying to find the simplest way (i.e. performance doesn't matter) of translating Exposure Time values to/from usable data. There is (as far as I can find) no standard for what values camera manufacturers might use i.e. I can't just scan the web for random images and hard-code a map.
Here are is a sample set of values I've encountered (" indicates seconds):
279", 30", 5", 3.2", 1.6", 1.3", 1", 1/1.3, 1/1.6, 1/2, 1/2.5, 1/3, 1/4, 1/5, 1/8, 1/13, 1/8000, 1/16000
Also take into consideration that I'd also like to find the average (mean) ... but it should be one of the actual shutter speeds collected and not just some arbitrary number.
EDIT:
By usable data I mean some sort of creative? numbering system that I can convert to/from for performing calculations. I thought about just multiplying everything by 1,000,000 except some fractions when divided are quite exotic.
EDIT #2:
To clarify, I'm using ExposureTime instead of ShutterSpeed because it contains photographer friendly values e.g. 1/50. ShutterSpeed is more of an approximation (which varies between camera manufacturers) and leads to values such as 1/49.
You want to parse them into some kind of time-duration object.
A simple way, looking at that data, would be to check wheter " or / occurs, if " parse as seconds, / parse as fraction of seconds. I don't really understand what else you could mean. For an example you'd need to specify a language--also, there might be a parser out there already.
Shutter speed is encoded in the EXIF metadata as an SRATIONAL, 32-bits for the numerator and 32-bits for the denominator. Sample code that retrieves it, using System.Drawing:
var bmp = new Bitmap(#"c:\temp\canon-ixus.jpg");
if (bmp.PropertyIdList.Contains(37377)) {
byte[] spencoded = bmp.GetPropertyItem(37377).Value;
int numerator = BitConverter.ToInt32(spencoded, 0);
int denominator = BitConverter.ToInt32(spencoded, 4);
Console.WriteLine("Shutter speed = {0}/{1}", numerator, denominator);
}
Output: Shutter speed = 553859/65536, sample image retrieved here.
It seems there are three types of string you will encounter:
String with double quotes " for seconds
String with leading 1/
String with no special characters
I propose you simply test for these conditions and parse the value accordingly using floats:
string[] InputSpeeds = new[] { "279\"", "30\"", "5\"", "3.2\"", "1.6\"", "1.3\"", "1\"", "1/1.3", "1/1.6", "1/2", "1/2.5", "1/3", "1/4", "1/5", "1/8", "1/13", "1/8000", "1/16000" };
List<float> OutputSpeeds = new List<float>();
foreach (string s in InputSpeeds)
{
float ConvertedSpeed;
if (s.Contains("\""))
{
float.TryParse(s.Replace("\"", String.Empty), out ConvertedSpeed);
OutputSpeeds.Add(ConvertedSpeed);
}
else if (s.Contains("1/"))
{
float.TryParse(s.Remove(0, 2), out ConvertedSpeed);
if (ConvertedSpeed == 0)
{
OutputSpeeds.Add(0F);
}
else
{
OutputSpeeds.Add(1 / ConvertedSpeed);
}
}
else
{
float.TryParse(s, out ConvertedSpeed);
OutputSpeeds.Add(ConvertedSpeed);
}
}
If you want TimeSpans simply change the List<float> to List<TimeSpan> and instead of adding the float to the list, use TimeSpan.FromSeconds(ConvertedSpeed);