JFreeChart XY plot: change domain scale - jfreechart

I create the following XY chart:
In this instance, I have two axes, each with two series. And each series has 39 points.
I would like to know how to change the scale of the domain axis, so for example instead of 0-39, it would show 0-3.9.
How can this be achieved? My code for the graph is below:
private final static int SERIES_MIN = 0;
private final static int SERIES_MAX = 1;
private JFreeChart createXYLineChart(String title) {
XYDataset voltageDataset = createXYVoltageDataset();
XYDataset currentDataset = createXYCurrentDataset();
XYLineAndShapeRenderer rVoltage = new XYLineAndShapeRenderer();
rVoltage.setSeriesPaint(SERIES_MIN, new Color(0xAA, 0xAA, 0xFF));
rVoltage.setSeriesPaint(SERIES_MAX, new Color(0x00, 0x00, 0xAA));
rVoltage.setSeriesShapesVisible(SERIES_MIN, false);
rVoltage.setSeriesShapesVisible(SERIES_MAX, false);
float dashVoltage[] = {1.0f, 5f}; // on, off
rVoltage.setSeriesStroke(SERIES_MIN, new BasicStroke(2.5f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER, 5, dashVoltage, 0));
rVoltage.setSeriesStroke(SERIES_MAX, new BasicStroke(1f));
XYLineAndShapeRenderer rCurrent = new XYLineAndShapeRenderer();
rCurrent.setSeriesPaint(SERIES_MIN, new Color(0x66, 0xAA, 0x66));
rCurrent.setSeriesPaint(SERIES_MAX, new Color(0x00, 0x44, 0x00));
rCurrent.setSeriesShapesVisible(SERIES_MIN, false);
rCurrent.setSeriesShapesVisible(SERIES_MAX, false);
float dashCurrent[] = {1.0f, 5f}; // on, off
rCurrent.setSeriesStroke(SERIES_MIN, new BasicStroke(2.5f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER, 5, dashCurrent, 0));
rCurrent.setSeriesStroke(SERIES_MAX, new BasicStroke(1));
JFreeChart chart = ChartFactory.createXYLineChart("Profile", "Set Current", "Voltage", null);
XYPlot plot = (XYPlot) chart.getPlot();
plot.setDataset(SERIES_MIN, voltageDataset);
plot.setRenderer(SERIES_MIN, rVoltage);
plot.setDataset(SERIES_MAX, currentDataset);
plot.setRenderer(SERIES_MAX, rCurrent);
plot.setRangeAxis(SERIES_MAX, new NumberAxis("Actual Current"));
plot.mapDatasetToRangeAxis(SERIES_MAX, SERIES_MAX); //2nd dataset to 2nd y-axi
plot.setBackgroundPaint(new Color(0xFF, 0xFF, 0xFF));
plot.setDomainGridlinePaint(new Color(0x00, 0x00, 0xff));
plot.setRangeGridlinePaint(new Color(0xff, 0x00, 0x00));
return chart;
}
private XYDataset createXYVoltageDataset() {
final XYSeries s1 = new XYSeries("Min Voltage");
final XYSeries s2 = new XYSeries("Max Voltage");
for (int i = 0; i < profile.getNumSteps(); i++) s1.add(i, profile.getStepMinVoltage(i));
for (int i = 0; i < profile.getNumSteps(); i++) s2.add(i, profile.getStepMaxVoltage(i));
XYSeriesCollection dataset = new XYSeriesCollection();
dataset.addSeries(s1);
dataset.addSeries(s2);
return dataset;
}
private XYDataset createXYCurrentDataset() {
final XYSeries s1 = new XYSeries("Min Current");
final XYSeries s2 = new XYSeries("Max Current");
for (int i = 0; i < profile.getNumSteps(); i++){
s1.add(i, profile.getStepMinCurrent(i));
}
for (int i = 0; i < profile.getNumSteps(); i++) s2.add(i, profile.getStepMaxCurrent(i));
XYSeriesCollection dataset = new XYSeriesCollection();
dataset.addSeries(s1);
dataset.addSeries(s2);
return dataset;
}

You should be able to use setRange() on the domain axis.
NumberAxis domainAxis = new NumberAxis("Set Current");
domainAxis.setRange(0, 3.9);
plot.setDomainAxis(SERIES_MAX, domainAxis);

Related

C# Image to PathGeometry

I am trying to Convert an Image to a PathGeometry. I upload a picture, and then I do canny edge detection and now I want to convert that in to a PathGeometry. My over all plan it to fill it with different colors.
So I tried this :`public Shape MakeSape(Brush customColor, double[,] image)
{
Path graphPath = new Path();
graphPath.Fill = customColor;
graphPath.Stroke = Brushes.Black;
PathFigure pf = new PathFigure();
pf.StartPoint = new Point(0, 0);
pf.IsClosed = true;
int row = image.GetLength(0);
int column = image.GetLength(1);
for (int y = 0; y < row; y++)
{
for (int x = 0; x < column; x++)
{
if (image[y, x] >= LowThreshold)
{
pf.Segments.Add(new LineSegment(new Point(x, y), true));
}
}
}
PathGeometry pg = new PathGeometry();
pg.Figures.Add(pf);
graphPath.Data = pg;
ImageAsShape = graphPath;
return graphPath;
}`
And that looked like it should work, but I am just getting all black.

JFreeChart XYLineAndShapeRenderer show unwanted vales outside range start and finish

Im build a series graph with jfreechart using XYLineAndShapeRenderer, this series need to show values for each day of a month, then I need that the X axis shows values from 1 to 30 or 1 to 31 (depend of current month). The dataset only have X values from 1 to 30/31, but the resultant graph shows ZERO(before 1) and 31/32 after(30/31). I want to show only 1 to 30/31 on X axis. But I dont have success. Follow shows the code that build dataset and graph and resultante image.
How I can show only valid values on X axis in this case ?
// build dataset
private XYDataset createSampleData()
{
List<Integer> diario = new ArrayList<>(Arrays.asList(20, 50, 120, 78, 37, 69, 145));
int dSize = diario.size();
int dPos = 0;
XYSeries serieD = new XYSeries("Diário");
XYSeries serieA = new XYSeries("Acumulado");
int acumulado = 0;
for(int i=1; i < 31; i++) {
int valDay = diario.get(dPos++);
acumulado += valDay;
serieD.add(i, valDay);
serieA.add(i, acumulado);
if( dPos >= dSize ) {
dPos = 0;
}
}
XYSeriesCollection result = new XYSeriesCollection(serieD);
result.addSeries(serieA);
return result;
}
private JFreeChart buildSeriesChartBySeriesData(String title, String labelX, String labelY)
{
NumberAxis xAxis = new NumberAxis(labelX);
xAxis.setAutoRangeIncludesZero(false);
xAxis.setRangeType(RangeType.POSITIVE);
NumberAxis yAxis = new NumberAxis(labelY);
yAxis.setAutoRangeIncludesZero(false);
yAxis.setRangeType(RangeType.POSITIVE);
XYSplineRenderer renderer1 = new XYSplineRenderer();
XYPlot plot = new XYPlot(this.createSampleData(), xAxis, yAxis, renderer1);
plot.setDomainGridlinesVisible(true);
plot.setDomainZeroBaselineVisible(false);
plot.setDomainPannable(false);
plot.setBackgroundPaint(new Color(224, 224,235));
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
plot.setDomainAxisLocation(AxisLocation.BOTTOM_OR_LEFT);
plot.setRangeAxisLocation(AxisLocation.TOP_OR_LEFT);
plot.setDomainPannable(false);
plot.setRangePannable(false);
plot.setDomainZeroBaselineVisible(false);
plot.setRangeZeroBaselineVisible(false);
renderer1.setSeriesPaint(0, Color.blue);
renderer1.setSeriesPaint(1, Color.yellow);
plot.setAxisOffset(new RectangleInsets(3, 3, 3, 3));
plot.setDomainCrosshairVisible(true);
plot.setRangeCrosshairVisible(true);
XYLineAndShapeRenderer localXYLineAndShapeRenderer = (XYLineAndShapeRenderer) plot.getRenderer();
localXYLineAndShapeRenderer.setBaseShapesVisible(true);
localXYLineAndShapeRenderer.setBaseShapesFilled(true);
localXYLineAndShapeRenderer.setDrawOutlines(true);
NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
// show item labels:
final XYItemRenderer renderer = plot.getRenderer();
ItemLabelPosition position = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_CENTER);
renderer.setBasePositiveItemLabelPosition(position);
final StandardXYItemLabelGenerator generator = new StandardXYItemLabelGenerator();
renderer.setSeriesItemLabelGenerator(0, generator);
renderer.setSeriesItemLabelsVisible(0, true);
renderer.setSeriesItemLabelGenerator(1, generator);
renderer.setSeriesItemLabelsVisible(1, true);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, true);
return chart;
}
In the next graph, I draw with timeSeries, and the results is the same, showing the last day of previos month and first day of next month, I don not want to show this values.
The result that I need is like this image(a sample from chartJs):
How I can hide the zero and 31 from result of first top graph ?
long time later...
---- after a long time I make the desired graph myself -----
This code generates the right graph:
private JFreeChart TimeSeriesChartExample()
{
XYDataset dataset = createSampleMonthData();
// Create chart
JFreeChart chart = ChartFactory.createTimeSeriesChart(
"Time Series Chart Example",
"Date",
"Values",
dataset, true, true, false);
// Changes background color
XYPlot plot = (XYPlot)chart.getPlot();
plot.setBackgroundPaint(new Color(224, 224,235));
XYSplineRenderer renderer1 = new XYSplineRenderer();
renderer1.setSeriesPaint(0, Color.blue);
renderer1.setSeriesPaint(1, Color.green);
plot.setRenderer(renderer1);
plot.setAxisOffset(new RectangleInsets(3, 3, 3, 3));
// show item labels:
XYItemRenderer renderer = plot.getRenderer();
ItemLabelPosition position = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_CENTER);
renderer.setBasePositiveItemLabelPosition(position);
final StandardXYItemLabelGenerator generator = new StandardXYItemLabelGenerator();
renderer.setSeriesItemLabelGenerator(0, generator);
renderer.setSeriesItemLabelsVisible(0, true);
renderer.setSeriesItemLabelGenerator(1, generator);
renderer.setSeriesItemLabelsVisible(1, true);
DateAxis xAxis = (DateAxis)plot.getDomainAxis();
xAxis.setDateFormatOverride(new SimpleDateFormat("dd/MM/yy"));
ValueAxis domainAxis = plot.getDomainAxis();
domainAxis.setVerticalTickLabels(true);
return chart;
}
This is the resultando graph:
The solution is the follow, I put on the question body too:
private JFreeChart TimeSeriesChartExample()
{
XYDataset dataset = createSampleMonthData();
JFreeChart chart = ChartFactory.createTimeSeriesChart(
"Time Series Chart Example",
"Date",
"Values",
dataset, true, true, false);
// Changes background color
XYPlot plot = (XYPlot)chart.getPlot();
plot.setBackgroundPaint(new Color(224, 224,235));
XYSplineRenderer renderer1 = new XYSplineRenderer();
renderer1.setSeriesPaint(0, Color.blue);
renderer1.setSeriesPaint(1, Color.green);
plot.setRenderer(renderer1);
plot.setAxisOffset(new RectangleInsets(3, 3, 3, 3));
XYItemRenderer renderer = plot.getRenderer();
ItemLabelPosition position = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_CENTER);
renderer.setBasePositiveItemLabelPosition(position);
final StandardXYItemLabelGenerator generator = new StandardXYItemLabelGenerator();
renderer.setSeriesItemLabelGenerator(0, generator);
renderer.setSeriesItemLabelsVisible(0, true);
renderer.setSeriesItemLabelGenerator(1, generator);
renderer.setSeriesItemLabelsVisible(1, true);
DateAxis xAxis = (DateAxis)plot.getDomainAxis();
xAxis.setDateFormatOverride(new SimpleDateFormat("dd/MM/yy"));
ValueAxis domainAxis = plot.getDomainAxis();
domainAxis.setVerticalTickLabels(true);
return chart;
}
This is the result:
Code as tested:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.JFrame;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.labels.ItemLabelAnchor;
import org.jfree.chart.labels.ItemLabelPosition;
import org.jfree.chart.labels.StandardXYItemLabelGenerator;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYSplineRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.RectangleInsets;
import org.jfree.ui.TextAnchor;
/**
* #see https://stackoverflow.com/a/49909020/230513
*/
public class ChartTest {
private void display() {
JFrame f = new JFrame("ChartTest");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new ChartPanel(createTimeSeriesChartExample()){
#Override
public Dimension getPreferredSize() {
return new Dimension(1000, 400);
}
});
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private XYDataset createSampleMonthData() {
List<Integer> diario = new ArrayList<>(
Arrays.asList(20, 50, 120, 78, 37, 69, 145));
int dSize = diario.size();
int dPos = 0;
XYSeries serieD = new XYSeries("Diário");
XYSeries serieA = new XYSeries("Acumulado");
int acumulado = 0;
for (int i = 1; i < 31; i++) {
int valDay = diario.get(dPos++);
acumulado += valDay;
serieD.add(i, valDay);
serieA.add(i, acumulado);
if (dPos >= dSize) {
dPos = 0;
}
}
XYSeriesCollection result = new XYSeriesCollection(serieD);
result.addSeries(serieA);
return result;
}
private JFreeChart createTimeSeriesChartExample() {
XYDataset dataset = createSampleMonthData();
JFreeChart chart = ChartFactory.createTimeSeriesChart(
"Time Series Chart Example",
"Date",
"Values",
dataset, true, true, false);
// Changes background color
XYPlot plot = (XYPlot) chart.getPlot();
plot.setBackgroundPaint(new Color(224, 224, 235));
XYSplineRenderer renderer1 = new XYSplineRenderer();
renderer1.setSeriesPaint(0, Color.blue);
renderer1.setSeriesPaint(1, Color.green);
plot.setRenderer(renderer1);
plot.setAxisOffset(new RectangleInsets(3, 3, 3, 3));
XYItemRenderer renderer = plot.getRenderer();
ItemLabelPosition position = new ItemLabelPosition(
ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_CENTER);
renderer.setBasePositiveItemLabelPosition(position);
final StandardXYItemLabelGenerator generator =
new StandardXYItemLabelGenerator();
renderer.setSeriesItemLabelGenerator(0, generator);
renderer.setSeriesItemLabelsVisible(0, true);
renderer.setSeriesItemLabelGenerator(1, generator);
renderer.setSeriesItemLabelsVisible(1, true);
DateAxis xAxis = (DateAxis) plot.getDomainAxis();
xAxis.setDateFormatOverride(new SimpleDateFormat("dd/MM/yy"));
ValueAxis domainAxis = plot.getDomainAxis();
domainAxis.setVerticalTickLabels(true);
return chart;
}
public static void main(String[] args) {
EventQueue.invokeLater(new ChartTest()::display);
}
}

Update Jfreechart when update data from Webcam

My jfreeChart comes from frames of a webcam. I pass this frames and it generates a graphic of R, G and B colors of this frame. I want this chart do automatic update as I pass the frames. I've tried everything but nothing seens to work.
Any help is welcome.
class DaemonThread implements Runnable
{
protected volatile boolean runnable = false;
#Override
public void run()
{
synchronized(this)
{
while(runnable)
{
if(webSource.grab())
{
try
{
webSource.retrieve(frame);
Imgcodecs.imencode(".bmp", frame, mem);
Image im = ImageIO.read(new ByteArrayInputStream(mem.toArray()));
buff = (BufferedImage) im;
if(contHistograma==0) {
h = new Histo(buff);
contHistograma++;
}else{
h.update(buff);
}
webcamLabel.setIcon(new ImageIcon(buff));
Graphics g=webcamPanel.getGraphics();
if (g.drawImage(buff, 0, 0, getWidth(), getHeight() -150 , 0, 0, buff.getWidth(), buff.getHeight(), null))
if(runnable == false)
{
System.out.println("Going to wait()");
this.wait();
}
}
catch(Exception ex)
{
System.out.println("Error");
}
}
}
}
}
}
public class Histo{
private ChartFrame lineFrame;
private ArrayList<Integer> redArray;
private ArrayList<Integer> greenArray;
private ArrayList<Integer> blueArray;
public Histo(BufferedImage originalImage){
Color c;
redArray = new ArrayList<>();
greenArray = new ArrayList<>();
blueArray = new ArrayList<>();
for (int i = 0; i < originalImage.getWidth(null); i++) {
for (int j = 0; j < originalImage.getHeight(null); j++) {
c = new Color(originalImage.getRGB(i,j));
redArray.add(c.getRed());
greenArray.add(c.getGreen());
blueArray.add(c.getBlue());
}
}
Collections.sort(redArray);
Collections.sort(greenArray);
Collections.sort(blueArray);
XYSeriesCollection dataset = creatingDataset(redArray, greenArray, blueArray);
JFreeChart chart = createChart(dataset);
ChartPanel chartPanel = new ChartPanel(chart);
lineFrame = new ChartFrame("teste", chart);
lineFrame.add(chartPanel);
lineFrame.setVisible(true);
lineFrame.setSize(600, 450);
}
public void update(BufferedImage originalImage){
redArray.clear();
greenArray.clear();
blueArray.clear();
Color c;
for (int i = 0; i < originalImage.getWidth(null); i++) {
for (int j = 0; j < originalImage.getHeight(null); j++) {
c = new Color(originalImage.getRGB(i,j));
redArray.add(c.getRed());
greenArray.add(c.getGreen());
blueArray.add(c.getBlue());
}
}
Collections.sort(redArray);
Collections.sort(greenArray);
Collections.sort(blueArray);
XYSeriesCollection dataset = creatingDataset(redArray, greenArray, blueArray);
JFreeChart chart = createChart(dataset);
ChartPanel chartPanel = new ChartPanel(chart);
lineFrame.removeAll();
lineFrame.add(chartPanel);
lineFrame.revalidate();
lineFrame.setLayout(new BorderLayout());
lineFrame.repaint();
}
public static XYSeriesCollection creatingDataset(ArrayList<Integer> redArray,ArrayList<Integer> greenArray,ArrayList<Integer> blueArray){
int cont=1, cont2=1, cont3=1;
XYSeries series = new XYSeries("Red");
XYSeries series2 = new XYSeries("Green");
XYSeries series3 = new XYSeries("Blue");
for (int i = 0; i < redArray.size()-1; i++) {
if(redArray.get(i).intValue() == redArray.get(i+1).intValue()) {
cont++;
}else{
series.add(redArray.get(i).intValue(), cont);
cont=1;
}
}
for (int i = 0; i < greenArray.size()-1; i++) {
if(greenArray.get(i).intValue() == greenArray.get(i + 1).intValue()) {
cont2++;
}else{
series2.add(greenArray.get(i).intValue(), cont2);
cont2 = 1;
}
}
for (int i = 0; i < blueArray.size()-1; i++) {
if(blueArray.get(i).intValue() == blueArray.get(i+1).intValue()) {
cont3++;
}else{
series3.add(blueArray.get(i).intValue(), cont3);
cont3=1;
}
}
XYSeriesCollection dataset = new XYSeriesCollection();
dataset.addSeries(series);
dataset.addSeries(series2);
dataset.addSeries(series3);
return dataset;
}
private JFreeChart createChart(final XYDataset dataset) {
JFreeChart result = ChartFactory.createXYLineChart("Gráfico XY", "Eixo X", "Eixo Y", dataset, PlotOrientation.VERTICAL, true, true, false);
final XYPlot plot = result.getXYPlot();
plot.setBackgroundPaint(new Color(0xffffe0));
plot.setDomainGridlinesVisible(true);
plot.setDomainGridlinePaint(Color.lightGray);
plot.setRangeGridlinesVisible(true);
plot.setRangeGridlinePaint(Color.lightGray);
final NumberAxis domainAxis = (NumberAxis) plot.getDomainAxis(); //RANGE EIXO X
domainAxis.setRange(0, 260);
final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis(); //RANGE EIXO Y
rangeAxis.setRange(0, 5000);
return result;
}
}
If someone else have this problem here is the answer:
Chartframe can't get rid of chartpanel, so I made Chartpanel a atribute.
After that I update my dataset and did this:
JFreeChart chart = createChart(dataset);
chartPanel.setChart(chart);
lineFrame.setLayout(new BorderLayout());
lineFrame.repaint();
Problem solved.

How to crop image and save into ImageSource in WPF?

I am new learner to WPF. here I got a question.
I have a image, width:360, height:360. Here I want to crop this image like below:
( 0,0 ) to (120,120) save to the first ImageSource object,
(120,0 ) to (240,120) save to the second ImageSource object,
(240,0 ) to (360,120) save to the third ImageSource object;,
……
pls see more details in below picture:
My code sample below:
private void CutImage(string img)
{
int iLeft = 0;
int iTop = 0;
int count = 0;
Image thisImg = new Image();
BitmapImage src = new BitmapImage();
src.BeginInit();
src.UriSource = new Uri(img, UriKind.Relative);
src.CacheOption = BitmapCacheOption.OnLoad;
src.EndInit();
thisImg.Source = src;
for (int i = 0; i < 3; i++)
{
iTop = i * 120;
for (int j = 0; j < 3; j++)
{
iLeft = j * 120;
Canvas canvas = new Canvas();
Rectangle destRect = new Rectangle();
destRect.SetValue(Canvas.LeftProperty, (double)0);
destRect.SetValue(Canvas.TopProperty,(double)0);
destRect.Width = destRect.Height = 120;
Rect srcRect = new Rect();
srcRect.X = iLeft;
srcRect.Y = iTop;
srcRect.Width = srcRect.Height = 120;
thisImg.Clip = new RectangleGeometry(srcRect);
thisImg.Clip.SetValue(Canvas.TopProperty, (double)iTop);
thisImg.Clip.SetValue(Canvas.LeftProperty, (double)iLeft);
thisImg.Clip.SetValue(Canvas.WidthProperty, (double)120);
thisImg.Clip.SetValue(Canvas.HeightProperty,(double)120);
objImg[count++] = (ImageSource)thisImg.GetValue(Image.SourceProperty);
}
}
}
but it doesn't work as I expected, seems that all the ImageSource objects store the same image, not the corping part. Any one can help me ? thx.
Use CroppedBitmap to do this:
private void CutImage(string img)
{
int count = 0;
BitmapImage src = new BitmapImage();
src.BeginInit();
src.UriSource = new Uri(img, UriKind.Relative);
src.CacheOption = BitmapCacheOption.OnLoad;
src.EndInit();
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
objImg[count++] = new CroppedBitmap(src, new Int32Rect(j * 120, i * 120, 120, 120));
}
Just do:
private static BitmapSource CaptureScreen(Visual target, double dpiX, double dpiY)
{
if (target == null)
{
return null;
}
Rect bounds = VisualTreeHelper.GetDescendantBounds(target);
RenderTargetBitmap rtb = new RenderTargetBitmap((int)(bounds.Width * dpiX / 96.0),
(int)(bounds.Height * dpiY / 96.0),
dpiX,
dpiY,
PixelFormats.Pbgra32);
DrawingVisual dv = new DrawingVisual();
using (DrawingContext ctx = dv.RenderOpen())
{
VisualBrush vb = new VisualBrush(target);
ctx.DrawRectangle(vb, null, new Rect(new Point(), bounds.Size));
}
rtb.Render(dv);
return rtb;
}
VisualBrush part1 = new VisualBrush(yourVISUAL);
part1.ViewBoxUnits = ..Absolute;
part1.ViewBox = new Rect(x, y, width, height);
BitmapSource bitmapSource = CaptureScreen(part1, 96, 96);
using (var fileStream = new FileStream(filePath, FileMode.Create))
{
BitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
encoder.Save(fileStream);
}

How to draw a dynamic Grid with XNA

I'm trying to draw grid using the XNA framework, this grid should have a fixed dimension, during the execution of XNA, but should be given to the user the opportunity to customize it before launch the game page (I'm building my app with the silverlight/xna template).
Does anyone has a suggestion on how achieve this goal?
Thank you
Set a tileSize, and then draw a texture over the size of grid you want.
Here is some reworked code. This is how I would start with generating a tilemap, by using a 2d array.
int tileSize = 32;
Vector2 position = Vector2.Zero;
Texture2D gridTexture;
int[,] map = new int[,]
{
{1, 1, 0,},
{0, 1, 1,},
{1, 1, 0,},
};
Then add something like this to your draw function:
for (int i = 0; i <= map.GetUpperBound(0); i++)
{
for (int j = 0; j <= map.GetUpperBound(1); j++)
{
int textureId = map[i, j];
if (textureId != 0)
{
Vector2 texturePosition = new Vector2(i * tileSize, j * tileSize) + position;
//Here you would typically index to a Texture based on the textureId.
spriteBatch.Draw(gridTexture, texturePosition, null, Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0f);
}
}
}
ContentManager contentManager;
GameTimer timer;
SpriteBatch spriteBatch;
LifeGrid life;
int tileSize = 32;
Vector2 position = Vector2.Zero;
Texture2D gridTexture;
int[,] map;
public GamePage()
{
InitializeComponent();
// Get the content manager from the application
contentManager = (Application.Current as App).Content;
// Create a timer for this page
timer = new GameTimer();
//timer.UpdateInterval = TimeSpan.FromTicks(333333);
timer.UpdateInterval = TimeSpan.Zero;
timer.Update += OnUpdate;
timer.Draw += OnDraw;
List<Position> p = new List<Position>();
p.Add(new Position(1,1));
p.Add(new Position(1,4));
p.Add(new Position(1,5));
p.Add(new Position(1,6));
p.Add(new Position(1,7));
this.life = new LifeGrid(10, 10, p);
map = new int[,]{{1, 1, 0,},{0, 1, 1,},{1, 1, 0,},};
// LayoutUpdated += new EventHandler(GamePage_LayoutUpdated);
}
/// <summary>
/// Allows the page to draw itself.
/// </summary>
private void OnDraw(object sender, GameTimerEventArgs e)
{
// SharedGraphicsDeviceManager.Current.GraphicsDevice.Clear(Color.CornflowerBlue);
// SharedGraphicsDeviceManager.Current.GraphicsDevice.Clear(Color.Black);
// Draw the sprite
spriteBatch.Begin();
for (int i = 0; i <= map.GetUpperBound(0); i++)
{
for (int j = 0; j <= map.GetUpperBound(1); j++)
{
int textureId = map[i, j];
if (textureId != 0)
{
Vector2 texturePosition = new Vector2(i * tileSize, j * tileSize) + position;
//Here you would typically index to a Texture based on the textureId.
spriteBatch.Draw(gridTexture, texturePosition, null, Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0f);
}
}
}
spriteBatch.End();
}

Resources