Why does this image rendering benchmark crash on IOS but not in the simulator? - codenameone

I tried to get a grasp of image rendering performance and created some code which draws full screen images using mutable images and PNGs.
The code runs fine in the simulator but on an iPhone SE it crashes after 50 seconds or short before a million images.
Is it a bug or is there another explanation since it doesn't crash in the simulator and I cannot see a memory leak in jvisualvm?
Here is the code:
public class FormMeasureImage extends Form implements Painter {
abstract class Wallpaper implements Painter {
private Component componentParent;
public Wallpaper(Component aComponentParent) {
componentParent = aComponentParent;
}
public void paint(Graphics aGraphics, Rectangle aRectangle) {
aGraphics.drawImage(
getImage(new Dimension(componentParent.getWidth(), componentParent.getHeight())),
0,
0);
}
public abstract Image getImage(Dimension aDimension);
}
class WallpaperTiledIcons extends Wallpaper {
private Image image;
private Dimension dimension;
public WallpaperTiledIcons(Component aComponentParent) {
super(aComponentParent);
}
public Image getImage(Dimension aDimension) {
if ((null == image || !dimension.equals(aDimension)) && null != aDimension) {
dimension = new Dimension(aDimension);
Label labelPattern = new Label("1234567890");
Style styleLabelPattern = labelPattern.getAllStyles();
styleLabelPattern.setBorder(Border.createEmpty());
styleLabelPattern.setMargin(0, 0, 0, 0);
// byte[] bytes = new byte[4];
// Arrays.fill(bytes, Style.UNIT_TYPE_PIXELS);
// styleLabelPattern.setPaddingUnit(bytes);
styleLabelPattern.setPadding(0, 0, 0, 1);
Dimension preferredSizeLabelPattern = labelPattern.getPreferredSize();
labelPattern.setSize(preferredSizeLabelPattern);
Image imagePattern = Image.createImage(
preferredSizeLabelPattern.getWidth(),
preferredSizeLabelPattern.getHeight(),
0x00000000);
Graphics graphicsImagePattern = imagePattern.getGraphics();
graphicsImagePattern.setAlpha(255);
labelPattern.paint(graphicsImagePattern);
image = Image.createImage(
aDimension.getWidth(),
aDimension.getHeight(),
0xff606060);
Graphics graphics = image.getGraphics();
if (graphics.isAntiAliasingSupported()) {
graphics.setAntiAliased(true);
}
int canvasWidth = preferredSizeLabelPattern.getWidth(), canvasHeight = preferredSizeLabelPattern.getHeight();
int[] clip = graphics.getClip();
Rectangle rectangleClip = new Rectangle(clip[0], clip[1], clip[2], clip[3]);
int columns = (rectangleClip.getX() + rectangleClip.getWidth()) / canvasWidth + 1;
int rows = (rectangleClip.getY() + rectangleClip.getHeight()) / canvasHeight + 1;
for (int row = 0; row < rows; row++) {
for (int column = 0; column < columns; column++) {
int x = canvasWidth * column;
int y = canvasHeight * row;
Rectangle rectangle = new Rectangle(x, y, canvasWidth, canvasHeight);
if (!rectangleClip.intersects(rectangle)) {
continue;
}
graphics.drawImage(imagePattern, x, y);
}
}
}
return image;
}
}
abstract class Stage {
long millisTotal;
long tally;
TextArea textArea;
public Stage(String aName) {
textArea = new TextArea();
textArea.setEditable(false);
getContentPane().add(textArea);
stages.add(this);
}
abstract void perform();
abstract boolean isPainted();
}
private Wallpaper wallpaper;
private List<Stage> stages = new ArrayList<>();
private Iterator<Stage> iteratorStages;
private Image imageEncoded;
public FormMeasureImage() {
super("FormMeasureImage", new BoxLayout(BoxLayout.Y_AXIS));
setScrollableX(false);
setScrollableY(true);
Style styleForm = getAllStyles();
styleForm.setBgTransparency(255);
styleForm.setBgPainter(this);
TextArea textArea = new TextArea();
textArea.setEditable(false);
textArea.setText("Measuring image throughput.");
add(textArea);
}
#Override
public void paint(Graphics aGraphics, Rectangle aRectangle) {
if (null == iteratorStages) {
new Stage("create") {
void perform() {
long millisBefore = System.currentTimeMillis();
wallpaper = new WallpaperTiledIcons(FormMeasureImage.this);
wallpaper.getImage(aRectangle.getSize());
millisTotal += System.currentTimeMillis() - millisBefore;
tally++;
textArea.setText("create: " + millisTotal + " / " + tally);
}
boolean isPainted() {
return false;
}
};
new Stage("mutable") {
void perform() {
long millisBefore = System.currentTimeMillis();
for (int index = 0; index < 1000; index++) {
wallpaper.paint(aGraphics, aRectangle);
tally++;
}
millisTotal += System.currentTimeMillis() - millisBefore;
textArea.setText("mutable: " + millisTotal + " / " + tally);
}
boolean isPainted() {
return true;
}
};
new Stage("encoding") {
void perform() {
long millisBefore = System.currentTimeMillis();
try {
millisBefore = System.currentTimeMillis();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageIO.getImageIO().save(wallpaper.getImage(null), byteArrayOutputStream, ImageIO.FORMAT_PNG, 1);
byteArrayOutputStream.close();
imageEncoded = Image.createImage(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
tally++;
millisTotal += System.currentTimeMillis() - millisBefore;
textArea.setText("encoding: " + millisTotal + " / " + tally);
} catch (IOException e) {
throw new RuntimeException(e.toString());
}
millisTotal += System.currentTimeMillis() - millisBefore;
tally++;
textArea.setText("encoding: " + millisTotal + " / " + tally);
}
boolean isPainted() {
return false;
}
};
new Stage("encoded") {
void perform() {
long millisBefore = System.currentTimeMillis();
for (int index = 0; index < 1000; index++) {
aGraphics.drawImage(
imageEncoded,
0,
0);
tally++;
}
millisTotal += System.currentTimeMillis() - millisBefore;
textArea.setText("encoded: " + millisTotal + " / " + tally);
}
boolean isPainted() {
return true;
}
};
iteratorStages = stages.iterator();
}
while (!perform().isPainted()) {;}
}
private Stage perform() {
if (!iteratorStages.hasNext()) {
iteratorStages = stages.iterator();
}
Stage stage = iteratorStages.next();
stage.perform();
return stage;
}
}

It seems that the test case included an EDT violation of decoding off the EDT. This can work for some cases but because of the heavy usage it crashes.
Making UI code threadsafe is a difficult task which is doubly so cross platforms.

Related

unity array having 50 gameobjects but displays only 10 object

i have build a level menu with levels, i also created and empty array (GameObject[ ] lvlBut; )to store the level icons instantiated, but only 10 level icons are displayed on the screen where as i have 50 levels. for some reason its only taking 10 levels and i don’t t know where i have gone wrong. any suggestions?
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.UI;
using TMPro;
public class LevelSelector : MonoBehaviour{
public GameObject levelHolder;
public GameObject levelIcon;
public GameObject thisCanvas;
public int numberOfLevels = 50;
public Vector2 iconSpacing;
private Rect panelDimensions;
private Rect iconDimensions;
private int amountPerPage;
private int currentLevelCount;
int levelsUnlocked;
GameObject[] lvlBut;
void Start()
{
panelDimensions = levelHolder.GetComponent<RectTransform>().rect;
iconDimensions = levelIcon.GetComponent<RectTransform>().rect;
int maxInARow = Mathf.FloorToInt((panelDimensions.width + iconSpacing.x) / (iconDimensions.width + iconSpacing.x));
int maxInACol = Mathf.FloorToInt((panelDimensions.height + iconSpacing.y) / (iconDimensions.height + iconSpacing.y));
amountPerPage = maxInARow * maxInACol;
int totalPages = Mathf.CeilToInt((float)numberOfLevels / amountPerPage);
LoadPanels(totalPages);
}
void LoadPanels(int numberOfPanels)
{
GameObject panelClone = Instantiate(levelHolder) as GameObject;
PageSwiper swiper = levelHolder.AddComponent<PageSwiper>();
swiper.totalPages = numberOfPanels;
for (int i = 1; i <= numberOfPanels; i++)
{
GameObject panel = Instantiate(panelClone) as GameObject;
panel.transform.SetParent(thisCanvas.transform, false);
panel.transform.SetParent(levelHolder.transform);
panel.name = "Page-" + i;
panel.GetComponent<RectTransform>().localPosition = new Vector2(panelDimensions.width * (i - 1), 0);
SetUpGrid(panel);
int numberOfIcons = i == numberOfPanels ? numberOfLevels - currentLevelCount : amountPerPage;
LoadIcons(numberOfIcons, panel);
}
Destroy(panelClone);
}
void SetUpGrid(GameObject panel)
{
GridLayoutGroup grid = panel.AddComponent<GridLayoutGroup>();
grid.cellSize = new Vector2(iconDimensions.width, iconDimensions.height);
grid.childAlignment = TextAnchor.MiddleCenter;
grid.spacing = iconSpacing;
}
void LoadIcons(int numberOfIcons, GameObject parentObject)
{
for (int i = 1; i <= numberOfIcons; i++)
{
currentLevelCount++;
GameObject icon = Instantiate(levelIcon) as GameObject;
icon.transform.SetParent(thisCanvas.transform, false);
icon.transform.SetParent(parentObject.transform);
icon.name = "Level " + i;
icon.GetComponentInChildren<TextMeshProUGUI>().SetText(currentLevelCount.ToString());
}
lvlBut = GameObject.FindGameObjectsWithTag("LevelButton");
levelsUnlocked = PlayerPrefs.GetInt("levelsUnlocked", 1);
for (int i = 0; i < lvlBut.Length; i++)
{
lvlBut[i].GetComponentInChildren<Button>().interactable = false;
}
for (int i = 0; i < levelsUnlocked; i++)
{
lvlBut[i].GetComponentInChildren<Button>().interactable = true;
}
}
}

How to build a swipable intro screen?

A lot of apps have swipable intro screens - You know - those with the dots below which indicate the page one is currently viewing.
What would be the best way to create one in Codename One - a Container with snapToGrid?
I have my own implementation for this use case. There are two classes : TutoDialog which could be in your case the "intro screens" dialog and Caroussel with the dots indicator.
A tuto dialog has a title and some images in parameter. It automatically adjust the number of dots of the caroussel according to the number of images. For my use case, each image is a screenshot of my app with some advise. The tuto dialog contains 3 buttons to navigate between images (next/previous/finish).
public class Caroussel extends Container {
private final static Image CIRCLE = MainClass.getResources().getImage("circle-blue20.png");
private final static Image CIRCLE_EMPTY = MainClass.getResources().getImage("circle-empty-blue20.png");
private Label[] circles;
private int currentIndex = -1;
public Caroussel(int nbItems, boolean selectFirst) {
if (nbItems < 2 || nbItems > 50) {
throw new IllegalArgumentException("Can't create Caroussel component with nbItems<2 || nbItems>50 ! ");
}
this.circles = new Label[nbItems];
setLayout(new BoxLayout(BoxLayout.X_AXIS));
for (int i = 0; i < nbItems; i++) {
circles[i] = new Label("", CIRCLE_EMPTY);
add(circles[i]);
}
if (selectFirst) {
select(0);
}
}
public void select(int index) {
if (index >= 0 && index <= circles.length) {
if (currentIndex > -1) {
circles[currentIndex].setIcon(CIRCLE_EMPTY);
}
circles[index].setIcon(CIRCLE);
currentIndex = index;
repaint();
}
}
public void selectNext() {
if (currentIndex <= circles.length) {
select(currentIndex + 1);
}
}
public void selectPrevious() {
if (currentIndex >= 1) {
select(currentIndex - 1);
}
}}
And
public class TutoDialog extends Dialog {
private Caroussel caroussel = null;
public TutoDialog(String title, Image... images) {
if (images == null) {
return;
}
this.caroussel = new Caroussel(images.length, true);
setTitle(title);
setAutoAdjustDialogSize(true);
getTitleComponent().setUIID("DialogTitle2");
setBlurBackgroundRadius(8.5f);
Tabs tabs = new Tabs();
tabs.setSwipeActivated(false);
tabs.setAnimateTabSelection(false);
int px1 = DisplayUtil.getScaledPixel(800), px2 = DisplayUtil.getScaledPixel(600);
for (Image img : images) {
tabs.addTab("", new Label("", img.scaled(px1, px2)));
}
Container cButtons = new Container(new BorderLayout());
Button bSuivant = new Button("button.suivant");
Button bPrecedent = new Button("button.precedent");
Button bTerminer = new Button("button.terminer");
bPrecedent.setVisible(false);
bTerminer.setVisible(false);
bSuivant.addActionListener(new ActionListener<ActionEvent>() {
public void actionPerformed(ActionEvent evt) {
int currentInd = tabs.getSelectedIndex();
if (currentInd == 0) {
bPrecedent.setVisible(true);
}
if (currentInd + 1 <= tabs.getTabCount() - 1) {
if (caroussel != null)
caroussel.selectNext();
tabs.setSelectedIndex(currentInd + 1);
if (currentInd + 1 == tabs.getTabCount() - 1) {
bTerminer.setVisible(true);
bSuivant.setVisible(false);
cButtons.revalidate();
}
}
};
});
bPrecedent.addActionListener(new ActionListener<ActionEvent>() {
public void actionPerformed(ActionEvent evt) {
int currentInd = tabs.getSelectedIndex();
tabs.setSelectedIndex(currentInd - 1);
bSuivant.setVisible(true);
if (caroussel != null)
caroussel.selectPrevious();
if (currentInd - 1 == 0) {
bPrecedent.setVisible(false);
cButtons.revalidate();
}
};
});
bTerminer.addActionListener(new ActionListener<ActionEvent>() {
#Override
public void actionPerformed(ActionEvent evt) {
tabs.setSelectedIndex(0);
bPrecedent.setVisible(false);
bTerminer.setVisible(false);
bSuivant.setVisible(true);
if (caroussel != null)
caroussel.select(0);
TutoDialog.this.dispose();
}
});
cButtons.add(BorderLayout.WEST, bPrecedent).add(BorderLayout.CENTER, bSuivant).add(BorderLayout.EAST, bTerminer);
add(BoxLayout.encloseY(tabs, BoxLayout.encloseY(FlowLayout.encloseCenter(caroussel), cButtons)));
}
public static void showIfFirstTime(AbstractComponentController ctrl) {
if (ctrl == null) {
Log.p("Can't execute method showIfFirstTime(...) with null AbstractComponentController");
return;
}
String key = getKey(ctrl);
if (ctrl.getTutoDlg() != null && !Preferences.get(key, false)) {
Display.getInstance().callSerially(new Runnable() {
#Override
public void run() {
Preferences.set(key, true);
ctrl.getTutoDlg().show();
}
});
}
}
public static String getKey(AbstractComponentController ctrl) {
String key = "tuto" + ctrl.getClass().getSimpleName();
if (UserController.getCurrentUser() != null) {
key += "-" + UserController.getCurrentUser().getId();
}
return key;
}
public static boolean isAlreadyShown(AbstractComponentController ctrl) {
return Preferences.get(getKey(ctrl), false);
}
}
It's look like this :
OK - so that is my first attempt and I am pretty content with that:
private void showIntro() {
Display display = Display.getInstance();
int percentage = 60;
int snapWidth = display.getDisplayWidth() * percentage / 100;
int snapHeight = display.getDisplayHeight() * percentage / 100;
Dialog dialog = new Dialog(new LayeredLayout()) {
#Override
protected Dimension calcPreferredSize() {
return new Dimension(snapWidth, snapHeight);
}
};
Tabs tabs = new Tabs();
tabs.setTensileLength(0);
tabs.hideTabs();
int[] colors = {
0xc00000,
0x00c000,
0x0000c0,
0x909000,
0x009090,
};
for (int colorIndex = 0; colorIndex < colors.length; colorIndex++) {
Container containerElement = new Container() {
#Override
protected Dimension calcPreferredSize() {
return new Dimension(snapWidth, snapHeight);
}
};
Style style = containerElement.getAllStyles();
style.setBgTransparency(0xff);
style.setBgColor(colors[colorIndex]);
tabs.addTab("tab" + tabs.getTabCount(), containerElement);
}
int tabCount = tabs.getTabCount();
Button[] buttons = new Button[tabCount];
Style styleButton = UIManager.getInstance().getComponentStyle("Button");
styleButton.setFgColor(0xffffff);
Image imageDot = FontImage.createMaterial(FontImage.MATERIAL_LENS, styleButton);
for (int tabIndex = 0; tabIndex < tabCount; tabIndex++) {
buttons[tabIndex] = new Button(imageDot);
buttons[tabIndex].setUIID("Container");
final int tabIndexFinal = tabIndex;
buttons[tabIndex].addActionListener(aActionEvent -> tabs.setSelectedIndex(tabIndexFinal, true));
}
Container containerButtons = FlowLayout.encloseCenter(buttons);
dialog.add(tabs);
Button buttonWest = new Button("Skip");
buttonWest.setUIID("Container");
buttonWest.getAllStyles().setFgColor(0xffffff);
buttonWest.addActionListener(aActionEvent -> dialog.dispose());
Button buttonEast = new Button(">");
buttonEast.setUIID("Container");
buttonEast.getAllStyles().setFgColor(0xffffff);
buttonEast.addActionListener(aActionEvent -> {
int selectedIndex = tabs.getSelectedIndex();
if (selectedIndex < (tabs.getTabCount() - 1)) {
tabs.setSelectedIndex(selectedIndex + 1, true);
} else {
dialog.dispose();
}
});
Container containerSouth = BorderLayout.south(BorderLayout.centerAbsoluteEastWest(containerButtons, buttonEast, buttonWest));
Style styleContainerSouth = containerSouth.getAllStyles();
styleContainerSouth.setMarginUnit(
Style.UNIT_TYPE_DIPS,
Style.UNIT_TYPE_DIPS,
Style.UNIT_TYPE_DIPS,
Style.UNIT_TYPE_DIPS);
styleContainerSouth.setMargin(2, 2, 2, 2);
dialog.add(containerSouth);
SelectionListener selectionListener = (aOldSelectionIndex, aNewSelectionIndex) -> {
for (int buttonIndex = 0; buttonIndex < buttons.length; buttonIndex++) {
if (buttonIndex == aNewSelectionIndex) {
buttons[buttonIndex].getAllStyles().setOpacity(0xff);
} else {
buttons[buttonIndex].getAllStyles().setOpacity(0xc0);
}
}
buttonEast.setText((aNewSelectionIndex < (tabs.getTabCount() - 1)) ? ">" : "Finish");
buttonEast.getParent().animateLayout(400);
};
tabs.addSelectionListener(selectionListener);
dialog.addShowListener(evt -> {
buttonEast.getParent().layoutContainer();
selectionListener.selectionChanged(-1, 0);
});
Command command = dialog.showPacked(BorderLayout.CENTER, true);
}

WPF: Create XpsDocument Pagination

I am trying to create a Paginator that will in turn create an XpsDocument that I can preview with the and then print. I have the following code that I found on the web but do not understand how it is working.
The issue I am having is that if I run this as is, the pages are generated successfully. If I comment out the lines within OnRender() that generate the actual values of data (all the lines after Random...) I get pages that are about one row high and no text on them but they appear to be the correct length. What is it that is keeping the values of "Row Number" & "Column i" from being shown?
I have included 2 screen shots to illustrate.
public class TaxCodePrintPaginator : DocumentPaginator
{
private int _RowsPerPage;
private Size _PageSize;
private int _Rows;
private List<TaxCode> _dataList;
public TaxCodePrintPaginator(List<TaxCode> dt, int rows, Size pageSize)
{
_dataList = dt;
_Rows = rows;
PageSize = pageSize;
}
public override DocumentPage GetPage(int pageNumber)
{
int currentRow = _RowsPerPage * pageNumber;
var page = new PageElement(currentRow, Math.Min(_RowsPerPage, _Rows - currentRow))
{
Width = PageSize.Width,
Height = PageSize.Height
};
page.Arrange(new Rect(new Point(0, 0), PageSize));
return new DocumentPage(page);
}
public override bool IsPageCountValid
{ get { return true; } }
public override int PageCount
{ get { return (int)Math.Ceiling(_Rows / (double)_RowsPerPage); } }
public override Size PageSize
{
get { return _PageSize; }
set
{
_PageSize = value;
_RowsPerPage = 40;
//Can't print anything if you can't fit a row on a page
Debug.Assert(_RowsPerPage > 0);
}
}
public override IDocumentPaginatorSource Source
{ get { return null; } }
}
public class PageElement : UserControl
{
private const int PageMargin = 75;
private const int HeaderHeight = 25;
private const int LineHeight = 20;
private const int ColumnWidth = 140;
private int _CurrentRow;
private int _Rows;
public PageElement(int currentRow, int rows)
{
Margin = new Thickness(PageMargin);
_CurrentRow = currentRow;
_Rows = rows;
}
private static FormattedText MakeText(string text)
{
return new FormattedText(text, CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
new Typeface("Tahoma"), 14, Brushes.Black);
}
public static int RowsPerPage(double height)
{
return (int)Math.Floor((height - (2 * PageMargin)
- HeaderHeight) / LineHeight);
}
protected override void OnRender(DrawingContext dc)
{
Point curPoint = new Point(0, 0);
dc.DrawText(MakeText("Row Number"), curPoint);
curPoint.X += ColumnWidth;
for (int i = 1; i < 4; i++)
{
dc.DrawText(MakeText("Column " + i), curPoint);
curPoint.X += ColumnWidth;
}
curPoint.X = 0;
curPoint.Y += LineHeight;
dc.DrawRectangle(Brushes.Black, null, new Rect(curPoint, new Size(Width, 2)));
curPoint.Y += HeaderHeight - LineHeight;
Random numberGen = new Random();
for (int i = _CurrentRow; i < _CurrentRow + _Rows; i++)
{
dc.DrawText(MakeText(i.ToString()), curPoint);
curPoint.X += ColumnWidth;
for (int j = 1; j < 4; j++)
{
dc.DrawText(MakeText(numberGen.Next().ToString()), curPoint);
curPoint.X += ColumnWidth;
}
curPoint.Y += LineHeight;
curPoint.X = 0;
}
}
}
Before
After

Playing sound parallelly with System.Media.SoundPlayer.PlaySync() and AxWindowsMediaPlayer

I have created a WinForm application which contains an AxWMPLib.AxMediaPlayer in which I play some videos. I also have to play some other custom sounds in a different thread. For this I used System.Media.SoundPlayer.PlaySync(). This thread plays couple of sound files sequentially in a loop. The problem is when I pause/stop the video the button event sounds are played fine. But when the video is running, sometimes some of the sound files are skipped. And it happens randomly.
Could anyone give some explanation about the problem and how to over come it. I mean how could I play the both sounds and video in parallel.
The video is playing in the UI thread and the other sounds are playing from different thread.Please check out the code bellow:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using ElectroQ;
using ElectroQServer1.Entities;
using WMPLib;
using System.Media;
using System.Windows.Media;
namespace ElectroQServer1
{
public partial class Form1 : Form
{
Thread dbListenerThread;
IWMPPlaylist playlist;
//string[] tokenNumber = { "A001", "B002", "C003", "D004","E005", "F006", "G007","HAMB" };
//string[] counterNumber = { "01", "02", "03", "04", "05", "06", "07", "MB" };
public Form1()
{
InitializeComponent();
//ResizeRedraw = true;
this.SetStyle(System.Windows.Forms.ControlStyles.DoubleBuffer, true);
this.WindowState = FormWindowState.Maximized;
//this.FormBorderStyle = FormBorderStyle.None;
//this.TopMost = true;
dbListenerThread = new Thread(RefreshQueueBoard);
dbListenerThread.Start();
}
/// <summary>
/// This method is used to prevent the flickering of the window.
/// </summary>
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
public void RefreshQueueBoard()
{
//Thread.Sleep(000);
while (true)
{
List<QueueData> lstQData = DA.GetAllQueueData(" where service_status_id = 2 ");
printToken(lstQData);
printCounter(lstQData);
playSound(lstQData);
Thread.Sleep(1000);
}
}
public void playSound(List<QueueData> lstQData)
{
foreach (QueueData qData in lstQData)
{
if (!qData.SoundPlayed)
{
string strSoundFile;
PlaySoundFIle(#"Sounds/TN.WAV");
foreach (char c in qData.ServiceQueueSerial)
{
strSoundFile = string.Format(#"Sounds/{0}.WAV", c);
PlaySoundFIle(strSoundFile);
}
PlaySoundFIle(#"Sounds/CN.WAV");
foreach (char c in qData.ServiceCounterID)
{
strSoundFile = string.Format(#"Sounds/{0}.WAV", c);
PlaySoundFIle(strSoundFile);
}
string strUpdateQuery = string.Format("UPDATE electro_queue SET sound_played = 1 WHERE service_queue_serial = '{0}'", qData.ServiceQueueSerial);
DA.UpdateQueueData(strUpdateQuery);
}
}
}
public void PlaySoundFIle(string strFile)
{
//string[] files = new string[4] { #"Sounds/TN.WAV", #"Sounds/CN.WAV", #"Sounds/TN.WAV", #"Sounds/CN.WAV"};
//WaveIO wa = new WaveIO();
//wa.Merge(files, #"tempfile.wav");
//MediaPlayer wowSound = new MediaPlayer(); //Initialize a new instance of MediaPlayer of name wowSound
//wowSound.Open(new Uri(#"tempfile.wav", UriKind.Relative)); //Open the file for a media playback
//wowSound.Play();
using (var soundPlayer = new SoundPlayer(strFile))
{
soundPlayer.PlaySync(); // can also use soundPlayer.Play() but it misses some sound file.
}
}
private void printToken(List<QueueData> lstQData)
{
if (InvokeRequired)
{
this.Invoke(new MethodInvoker(delegate
{
pnlQStat.Controls.Clear();
string dir;
//int xpos = 55;
//int ypos = 207;
int xpos = 10;
int ypos = 00;
//int k=0;
for (int i = 0; i < lstQData.Count; i++)
{
/* if (i == 4 || i == 8)
{
ypos = ypos - 360;
xpos = 675;
}*/
foreach (char c in lstQData[i].ServiceQueueSerial)
{
if (i == 0)
{
dir = "Resources/_" + c + ".bmp";
}
else
{
dir = "Resources/" + c + ".bmp";
}
createPicBox(dir, "pBox" + i, xpos, ypos);
xpos = xpos + 43;
}
ypos = ypos + 50;
xpos = 10;
}
}));
return;
}
}
private void printCounter(List<QueueData> lstQData)
{
if (InvokeRequired)
{
this.Invoke(new MethodInvoker(delegate
{
//int xpos = 415;
//int ypos = 207;
//int xpos = 292;
int xpos = 220;
int ypos = 00;
//int k=0;
for (int i = 0; i < lstQData.Count; i++)
{
/*if (i == 4 || i == 8)
{
ypos = ypos - 360;
xpos = 1035;
}
*/
foreach (char c in lstQData[i].ServiceCounterID)
{
string dir;
if (i == 0)
{
dir = "Resources/_" + c + ".bmp";
}
else
{
dir = "Resources/" + c + ".bmp";
}
//string dir = "Resources/" + c + ".bmp";
createPicBox(dir, "pBox" + i, xpos, ypos);
xpos = xpos + 63;
}
ypos = ypos + 50;
xpos = xpos - 63;
}
}));
return;
}
}
private void createPicBox(string directory, string name, int xposition, int yposition)
{
PictureBox picBox = new System.Windows.Forms.PictureBox();
picBox.Name = name;
picBox.Location = new System.Drawing.Point(xposition, yposition);
picBox.Size = new System.Drawing.Size(40, 50);
picBox.BackgroundImage = Image.FromFile(directory);
picBox.BackgroundImageLayout = ImageLayout.Stretch;
pnlQStat.Controls.Add(picBox);
}
private void Form1_Load(object sender, EventArgs e)
{
createPlayList();
//dbListenerThread.Abort(); // this line of code should be placed in onClosing Event.
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
dbListenerThread.Abort();
player.playlistCollection.remove(playlist);
}
private void createPlayList()
{
playlist = player.playlistCollection.newPlaylist("mpl");
playlist.appendItem(player.newMedia(#"E:\SONGS\teri-meri-promo-Muskurahat.Com.wmv"));
playlist.appendItem(player.newMedia(#"E:\MOVZZZ\English\The Kid\THE KID FILM_1_0001.avi"));
player.currentPlaylist = playlist;
}
private void btnPlay_Click(object sender, EventArgs e)
{
// player.URL = #"E:\MOVZZZ\English\The Kid\THE KID FILM_1_0001.avi";
player.Ctlcontrols.play();
}
private void btnStop_Click(object sender, EventArgs e)
{
player.Ctlcontrols.stop();
}
}
}
My objective is to play the looped sound files sequentially with the video playing in parallel.
You should not use SoundPlayer for this purpose; SoundPlayer is a lightweight, convenience class for playing occasional incidental sounds in an application. It will occasionally skip sounds if other things are going on in the audio subsystem (like a video playing). Here is a good sample that shows how to use the low-level waveOutOpen API for playing sounds.

how to get the visible area of canvas in wpf

I am creating an application just like a paint in WPF, and I want to add zoom functionality to it. I am taking canvas as a parent and writable bitmap on it as child on which I draw. When the size of the canvas is small, I am drawing on writable bitmap smoothly, but when the size of the canvas is large, and zoom it, canvas size will be large, problem occur to draw on this large area. So I want to find the visible region of the canvas so that I can draw on it smoothly.
Please give me a source code to find the visible region of the canvas.
I have create this application:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Interop;
namespace MapDesigner.Controls
{
class MapCanvas : Canvas
{
#region Routed Events
public static readonly RoutedEvent SelectedColorChangeEvent = EventManager.RegisterRoutedEvent(
"SelectedColorChange", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ucToolBox));
public event RoutedEventHandler SelectedColorChange
{
add { AddHandler(SelectedColorChangeEvent, value); }
remove { RemoveHandler(SelectedColorChangeEvent, value); }
}
#endregion
#region Enums
public enum Tool
{
Pencil,
FloodFill,
Eraser,
RectSelect,
Brush,
Part
}
#endregion
WriteableBitmap _wBMP;
Image _dispImg = new Image();
ScaleTransform st = new ScaleTransform();
int canvasHeight, canvasWidth;
double zoomLevel = 1;
Border brdGrid = new Border();
Color cellColor = Colors.Black;
Tool currentTool = Tool.Pencil;
int[,] array;
bool drawing = false;
bool showGrids = true;
public TextBlock tbPos;
public Tool CurrentTool
{
get
{
return currentTool;
}
set
{
currentTool = value;
}
}
public Color CellColor
{
get
{
return cellColor;
}
set
{
cellColor = value;
}
}
public bool GridsVisible
{
get
{
return showGrids;
}
set
{
showGrids = value;
}
}
public MapCanvas()
{
this.Children.Clear();
this.Children.Add(_dispImg);
//st.ScaleX = 1;
//st.ScaleY = 1;
// this.LayoutTransform = st;
}
void Refresh()
{
//canvas = new MapCanvas();
this.Children.Clear();
this.Children.Add(_dispImg);
st.ScaleX = 1;
st.ScaleY = 1;
this.Height = 0;
this.Width = 0;
zoomLevel = 1;
drawing = false;
}
public void LoadBMP(Uri bmpUri)
{
Refresh();
BitmapImage bmi = new BitmapImage(bmpUri);
_wBMP = new WriteableBitmap(bmi);
_dispImg.Source = _wBMP;
this.Height = bmi.Height;
this.Width = bmi.Width;
ShowGrids();
}
public void CreateBMP(int width, int height)
{
Refresh();
_wBMP = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgr32, BitmapPalettes.WebPalette);
_wBMP.setPixel(Colors.White);
_dispImg.Source = _wBMP;
this.Height = height;
this.Width = width;
ShowGrids();
}
public void CreateNewDesign(Size mapSize)
{
Refresh();
_wBMP = new WriteableBitmap((int)mapSize.Width, (int)mapSize.Width, 96, 96, PixelFormats.Bgr32, BitmapPalettes.WebPalette);
_wBMP.setPixel(Colors.White);
_dispImg.Source = _wBMP;
array = new int[(_wBMP.PixelHeight + 1), (_wBMP.PixelWidth + 1)];
canvasWidth = (int)mapSize.Width;
canvasHeight = (int)mapSize.Height;
this.Height = mapSize.Height;
this.Width = mapSize.Width;
ShowGrids();
}
void ShowGrids()
{
return;
double width = 1;// _tileWidth + _tileMargin;
double height = 1;// _tileHeight + _tileMargin;
double numTileToAccumulate = 16;
Polyline gridCell = new Polyline();
gridCell.Margin = new Thickness(.5);
gridCell.Stroke = Brushes.LightBlue;
gridCell.StrokeThickness = 0.1;
gridCell.Points = new PointCollection(new Point[] { new Point(0, height-0.1),
new Point(width-0.1, height-0.1), new Point(width-0.1, 0) });
VisualBrush gridLines = new VisualBrush(gridCell);
gridLines.TileMode = TileMode.Tile;
gridLines.Viewport = new Rect(0, 0, 1.0 / numTileToAccumulate, 1.0 / numTileToAccumulate);
gridLines.AlignmentX = AlignmentX.Center;
gridLines.AlignmentY = AlignmentY.Center;
VisualBrush outerVB = new VisualBrush();
Rectangle outerRect = new Rectangle();
outerRect.Width = 10.0; //can be any size
outerRect.Height = 10.0;
outerRect.Fill = gridLines;
outerVB.Visual = outerRect;
outerVB.Viewport = new Rect(0, 0,
width * numTileToAccumulate, height * numTileToAccumulate);
outerVB.ViewportUnits = BrushMappingMode.Absolute;
outerVB.TileMode = TileMode.Tile;
this.Children.Remove(brdGrid);
brdGrid = new Border();
brdGrid.Height = this.Height;
brdGrid.Width = this.Width;
brdGrid.Background = outerVB;
this.Children.Add(brdGrid);
}
protected override void OnMouseMove(System.Windows.Input.MouseEventArgs e)
{
base.OnMouseMove(e);
tbPos.Text = (_wBMP.PixelWidth / zoomLevel).ToString() + "," + (_wBMP.PixelHeight / zoomLevel).ToString() + " | " + Math.Ceiling((((Point)e.GetPosition(this)).X) / zoomLevel).ToString() + "," + Math.Ceiling((((Point)e.GetPosition(this)).Y / zoomLevel)).ToString();
if (e.LeftButton == System.Windows.Input.MouseButtonState.Pressed)
{
Point pos = e.GetPosition(this);
int xPos = (int)Math.Ceiling((pos.X) / zoomLevel);
int yPos = (int)Math.Ceiling((pos.Y) / zoomLevel);
int xDraw = (int)Math.Ceiling(pos.X);
int yDraw = (int)Math.Ceiling(pos.Y);
array[xPos, yPos] = 1;
drawing = true;
SetPixelsFromArray((int)zoomLevel);
//for (int i = 0; i < zoomLevel; i++)
//{
// for (int j = 0; j < zoomLevel; j++)
// {
// _wBMP.setPixel(xDraw, yDraw, cellColor);
// _dispImg.Source = _wBMP;
// }
//}
//_wBMP.setPixel(xPos, yPos, cellColor);
//_wBMP.setPixel((int)pos.X, (int)pos.Y, cellColor);
//_dispImg.Source = _wBMP;
}
}
private void SetPixelsFromArray(int ZoomLevel)
{
for (int i = 1; i < _wBMP.PixelWidth / ZoomLevel; i++)
{
for (int j = 1; j < _wBMP.PixelHeight / ZoomLevel; j++)
{
if (array[i, j] == 1)
{
for (int k = 0; k < ZoomLevel; k++)
{
for (int l = 0; l < ZoomLevel; l++)
{
_wBMP.setPixel((int)(i * ZoomLevel + k), (int)(j * ZoomLevel + l), cellColor);
_dispImg.Source = _wBMP;
}
}
}
}
}
}
protected override void OnMouseUp(System.Windows.Input.MouseButtonEventArgs e)
{
//double d= this.ActualHeight;
//Double t =(double) this.GetValue(Canvas.TopProperty);
//double i = Convert.ToDouble(top);
getScreenRect();
if (e.ChangedButton == System.Windows.Input.MouseButton.Right)
{
if (cellColor == Colors.Black)
{
cellColor = Colors.Red;
}
else
{
cellColor = Colors.Black;
}
}
else if (e.ChangedButton == System.Windows.Input.MouseButton.Left)
{
Point pos = e.GetPosition(this);
int xPos = (int)Math.Ceiling((pos.X) / zoomLevel);
int yPos = (int)Math.Ceiling((pos.Y) / zoomLevel);
array[xPos, yPos] = 1;
drawing = true;
SetPixelsFromArray((int)zoomLevel);
//_wBMP.setPixel((int)pos.X, (int)pos.Y, cellColor);
//_dispImg.Source = _wBMP;
}
}
private void getScreenRect()
{
Visual _rootVisual = HwndSource.FromVisual(this).RootVisual;
GeneralTransform transformToRoot = this.TransformToAncestor(_rootVisual);
Rect screenRect = new Rect(transformToRoot.Transform(new Point(0, 0)), transformToRoot.Transform(new Point(this.ActualWidth, this.ActualHeight)));
DependencyObject parent = VisualTreeHelper.GetParent(this);
while (parent != null)
{
Visual visual = parent as Visual;
System.Windows.Controls.Control control = parent as System.Windows.Controls.Control;
if (visual != null && control != null)
{
transformToRoot = visual.TransformToAncestor(_rootVisual);
Point pointAncestorTopLeft = transformToRoot.Transform(new Point(0, 0));
Point pointAncestorBottomRight = transformToRoot.Transform(new Point(control.ActualWidth, control.ActualHeight));
Rect ancestorRect = new Rect(pointAncestorTopLeft, pointAncestorBottomRight);
screenRect.Intersect(ancestorRect);
}
parent = VisualTreeHelper.GetParent(parent);
//}
// at this point screenRect is the bounding rectangle for the visible portion of "this" element
}
// return screenRect;
}
protected override void OnMouseWheel(System.Windows.Input.MouseWheelEventArgs e)
{
base.OnMouseWheel(e);
if (e.Delta > 0)
{
zoomLevel *= 2;
}
else
{
zoomLevel /= 2;
}
if (zoomLevel > 8)
{
zoomLevel = 8;
}
if (zoomLevel <= 1)
{
zoomLevel = 1;
// brdGrid.Visibility = Visibility.Collapsed;
}
else
{
//brdGrid.Visibility = Visibility.Visible;
}
_wBMP = new WriteableBitmap((int)zoomLevel * canvasWidth, (int)zoomLevel * canvasHeight, 96, 96, PixelFormats.Bgr32, BitmapPalettes.WebPalette);
_wBMP.setPixel(Colors.White);
this.Width = zoomLevel * canvasWidth;
this.Height = zoomLevel * canvasHeight;
if (drawing == true)
{
SetPixelsFromArray((int)zoomLevel);
}
//this.InvalidateVisual();
}
internal bool SaveAsBMP(string fileName)
{
return true;
}
}
public static class bitmapextensions
{
public static void setPixel(this WriteableBitmap wbm, Color c)
{
if (!wbm.Format.Equals(PixelFormats.Bgr32))
return;
wbm.Lock();
IntPtr buff = wbm.BackBuffer;
int Stride = wbm.BackBufferStride;
int x = 0;
int y = 0;
for (x = 0; x < wbm.PixelWidth; x++)
{
for (y = 0; y < wbm.PixelHeight; y++)
{
unsafe
{
byte* pbuff = (byte*)buff.ToPointer();
int loc = y * Stride + x * 4;
pbuff[loc] = c.B;
pbuff[loc + 1] = c.G;
pbuff[loc + 2] = c.R;
//pbuff[loc + 3] = c.A;
}
}
}
wbm.AddDirtyRect(new Int32Rect(0, 0, x, y));
wbm.Unlock();
}
public static void setPixel(this WriteableBitmap wbm, int x, int y, Color c)
{
if (y > wbm.PixelHeight - 1 || x > wbm.PixelWidth - 1)
return;
if (y < 0 || x < 0)
return;
if (!wbm.Format.Equals(PixelFormats.Bgr32))
return;
wbm.Lock();
IntPtr buff = wbm.BackBuffer;
int Stride = wbm.BackBufferStride;
unsafe
{
byte* pbuff = (byte*)buff.ToPointer();
int loc = y * Stride + x * 4;
pbuff[loc] = c.B;
pbuff[loc + 1] = c.G;
pbuff[loc + 2] = c.R;
//pbuff[loc + 3] = c.A;
}
wbm.AddDirtyRect(new Int32Rect(x, y, 1, 1));
wbm.Unlock();
}
public static Color getPixel(this WriteableBitmap wbm, int x, int y)
{
if (y > wbm.PixelHeight - 1 || x > wbm.PixelWidth - 1)
return Color.FromArgb(0, 0, 0, 0);
if (y < 0 || x < 0)
return Color.FromArgb(0, 0, 0, 0);
if (!wbm.Format.Equals(PixelFormats.Bgr32))
return Color.FromArgb(0, 0, 0, 0);
IntPtr buff = wbm.BackBuffer;
int Stride = wbm.BackBufferStride;
Color c;
unsafe
{
byte* pbuff = (byte*)buff.ToPointer();
int loc = y * Stride + x * 4;
c = Color.FromArgb(pbuff[loc + 3], pbuff[loc + 2], pbuff[loc + 1], pbuff[loc]);
}
return c;
}
}
}
You should implement IScrollInfo on your canvas (or actually, create a custom Panel that inherits from Canvas and implements IScrollInfo).
That interface holds all that is relevant to your situation:
http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.iscrollinfo.aspx
http://blogs.msdn.com/b/jgoldb/archive/2008/03/08/performant-virtualized-wpf-canvas.aspx

Resources