/// <summary> /// Initializes a new instance of the VGImage class. /// Clone Constructor. Creates new <see cref="VGImage"/> that is /// identical to the given <see cref="VGImage"/>. /// </summary> /// <param name="cloneImage"><see cref="VGImage"/> to clone</param> private VGImage(VGImage cloneImage) : base( cloneImage.ShapeDrawAction, cloneImage.Pen, cloneImage.Brush, cloneImage.Font, cloneImage.FontColor, cloneImage.Bounds, cloneImage.StyleGroup, cloneImage.Name, cloneImage.ElementGroup, cloneImage.Sound) { this.filename = cloneImage.Filename; this.Filepath = cloneImage.Filepath; this.alpha = cloneImage.Alpha; // Removed because when starting recording that leaded // to an cross thread problem (object is in use elsewhere) // _image = image.StimulusImage; this.layout = cloneImage.Layout; this.canvas = cloneImage.Canvas; this.InitTransparencyMatrix(); }
/// <summary> /// Performs the attention map calculation. /// </summary> /// <param name="weightened"><strong>True</strong>, if length of /// fixations should weighten the fixations, otherwise <strong>false</strong></param> /// <param name="worker">background worker</param> /// <param name="e">Background worker event arguments</param> private void DrawAttentionMap(bool weightened, BackgroundWorker worker, DoWorkEventArgs e) { this.Elements.Clear(); // Read Eyetracker settings int eyeMonX = this.StimulusSize.Width; int eyeMonY = this.StimulusSize.Height; // init DistributionArray float[,] distributionArray = new float[eyeMonX, eyeMonY]; // Calculate gaussian kernel for each entry in Fixationtable and add it to Distributionarray int counterRows = 0; foreach (DataRow row in this.tableAttentionMap.Rows) { float posX = Convert.ToSingle(row["PosX"]); float posY = Convert.ToSingle(row["PosY"]); float[,] kernelMultiplied = null; if (weightened) { // 1 ms = 1 kernelMaximum float factor = (int)row["Length"]; kernelMultiplied = AttentionMaps.MultiplyKernel(factor, AttentionMaps.KernelSize); } else { // 1 Fixation = 1 kernelMaximum kernelMultiplied = AttentionMaps.DefaultKernel; } AttentionMaps.AddKernelToArray(distributionArray, (int)posX, (int)posY, eyeMonX, eyeMonY, AttentionMaps.KernelSize, kernelMultiplied); if (worker.CancellationPending) { e.Cancel = true; break; } else { // Report progress as a percentage of the total task. int percentComplete = Convert.ToInt32(Convert.ToSingle(counterRows) / this.tableAttentionMap.Rows.Count * 100); worker.ReportProgress(percentComplete, "Calculating Subject:" + row["SubjectName"].ToString()); } counterRows++; } ////this.valueForMaxColor = 20; AttentionMaps.RescaleArray(distributionArray, -1); Bitmap heatMapBitmap = AttentionMaps.CreateHeatMap( this.heatMap, this.colorMap, new Size(eyeMonX, eyeMonY), distributionArray); VGImage newImage = new VGImage(heatMapBitmap, ImageLayout.Center, new Size(eyeMonX, eyeMonY)); Elements.Add(newImage); heatMapBitmap.Dispose(); this.DrawForeground(true); }
/////////////////////////////////////////////////////////////////////////////// // Eventhandler for Custom Defined Events // /////////////////////////////////////////////////////////////////////////////// #region CUSTOMEVENTHANDLER #endregion //CUSTOMEVENTHANDLER #endregion //EVENTS /////////////////////////////////////////////////////////////////////////////// // Methods and Eventhandling for Background tasks // /////////////////////////////////////////////////////////////////////////////// #region BACKGROUNDWORKER #endregion //BACKGROUNDWORKER /////////////////////////////////////////////////////////////////////////////// // Methods for doing main class job // /////////////////////////////////////////////////////////////////////////////// #region PRIVATEMETHODS /// <summary> /// This method does the parsing of the given path and creates for each readable /// image or media file a trial with the defined conditions. /// </summary> /// <returns>A <see cref="List{Slide}"/> to be imported in the slideshow of /// the experiment.</returns> private List<Slide> GetSlides() { var newSlides = new List<Slide>(); var dirInfoStimuli = new DirectoryInfo(this.txbFolder.Text); if (dirInfoStimuli.Exists) { var files = dirInfoStimuli.GetFiles(); Array.Sort(files, new NumericComparer()); foreach (var file in files) { var extension = file.Extension.ToLower(); // Ignore files with unrecognized extensions switch (extension) { case ".bmp": case ".png": case ".jpg": case ".wmf": case ".mp3": case ".wav": case ".wma": break; default: continue; } // Ignore hidden and MAC files if (file.Name.StartsWith(".")) { continue; } var newSlide = new Slide { BackgroundColor = this.clbBackground.CurrentColor, Modified = true, MouseCursorVisible = this.chbShowMouseCursor.Checked, MouseInitialPosition = this.psbMouseCursor.CurrentPosition, Name = Path.GetFileNameWithoutExtension(file.Name), PresentationSize = Document.ActiveDocument.PresentationSize }; StopCondition stop = null; if (this.rdbTime.Checked) { stop = new TimeStopCondition((int)(this.nudTime.Value * 1000)); } else if (this.rdbKey.Checked) { string selectedItemKeys = (string)this.cbbKeys.SelectedItem; KeyStopCondition ksc = new KeyStopCondition(); if (selectedItemKeys == "Any") { ksc.CanBeAnyInputOfThisType = true; } else { ksc.StopKey = (Keys)Enum.Parse(typeof(Keys), selectedItemKeys); } stop = ksc; } else if (this.rdbMouse.Checked) { string selectedItemMouse = (string)this.cbbMouseButtons.SelectedItem; MouseStopCondition msc = new MouseStopCondition(); msc.CanBeAnyInputOfThisType = selectedItemMouse == "Any" ? true : false; if (!msc.CanBeAnyInputOfThisType) { msc.StopMouseButton = (MouseButtons)Enum.Parse(typeof(MouseButtons), selectedItemMouse); } msc.Target = string.Empty; stop = msc; } else if (this.rdbDuration.Checked) { if (extension == ".mp3" || extension == ".wav" || extension == ".wma") { int duration = this.GetAudioFileLength(file.FullName); if (duration != 0) { stop = new TimeStopCondition(duration + (int)this.nudLatency.Value); } else { stop = new TimeStopCondition((int)(this.nudTime.Value * 1000)); } } else { stop = new TimeStopCondition((int)(this.nudTime.Value * 1000)); } } newSlide.StopConditions.Add(stop); foreach (VGElement element in this.lsbStandardItems.Items) { newSlide.VGStimuli.Add(element); } string destination = Path.Combine(Document.ActiveDocument.ExperimentSettings.SlideResourcesPath, file.Name); switch (extension) { case ".bmp": case ".png": case ".jpg": case ".wmf": if (!File.Exists(destination)) { File.Copy(file.FullName, destination, true); } VGImage image = new VGImage( ShapeDrawAction.None, Pens.Red, Brushes.Red, SystemFonts.MenuFont, Color.Red, file.Name, Document.ActiveDocument.ExperimentSettings.SlideResourcesPath, ImageLayout.Stretch, 1f, Document.ActiveDocument.PresentationSize, VGStyleGroup.None, file.Name, string.Empty, true); newSlide.VGStimuli.Add(image); newSlides.Add(newSlide); break; case ".mp3": case ".wav": case ".wma": File.Copy(file.FullName, destination, true); VGSound sound = new VGSound(ShapeDrawAction.None, Pens.Red, new Rectangle(0, 0, 200, 300)); sound.Center = newSlide.MouseInitialPosition; sound.Size = new SizeF(50, 50); AudioFile audioFile = new AudioFile(); audioFile.Filename = file.Name; audioFile.Filepath = Document.ActiveDocument.ExperimentSettings.SlideResourcesPath; audioFile.Loop = false; audioFile.ShouldPlay = true; audioFile.ShowOnClick = false; sound.Sound = audioFile; newSlide.VGStimuli.Add(sound); newSlides.Add(newSlide); break; } } } return newSlides; }
/////////////////////////////////////////////////////////////////////////////// // Eventhandler // /////////////////////////////////////////////////////////////////////////////// #region EVENTS /////////////////////////////////////////////////////////////////////////////// // Eventhandler for Custom Defined Events // /////////////////////////////////////////////////////////////////////////////// #region CUSTOMEVENTHANDLER #endregion //CUSTOMEVENTHANDLER #endregion //EVENTS /////////////////////////////////////////////////////////////////////////////// // Methods for doing main class job // /////////////////////////////////////////////////////////////////////////////// #region METHODS /// <summary> /// This method creates the attention map with the current /// visualization settings from the given distribution array. /// </summary> /// <param name="sampleType">The <see cref="SampleType"/> /// the attention map is created for.</param> protected void ApplyAttentionMap(SampleType sampleType) { int eyeMonX = this.StimulusSize.Width; int eyeMonY = this.StimulusSize.Height; // Finish attention map drawing if applicable if ((sampleType == (sampleType | SampleType.Gaze) && this.gazeDrawingMode == FixationDrawingMode.AttentionMap) || (sampleType == (sampleType | SampleType.Mouse) && this.mouseDrawingMode == FixationDrawingMode.AttentionMap)) { AttentionMaps.RescaleArray(this.distributionArray, -1); Bitmap heatMapBitmap = AttentionMaps.CreateHeatMap( this.heatMap, this.colorMap, new Size(eyeMonX, eyeMonY), this.distributionArray); VGImage newImage = new VGImage(heatMapBitmap, ImageLayout.Center, new Size(eyeMonX, eyeMonY)); newImage.Name = "HeatMap"; heatMapBitmap.Dispose(); this.Elements.Remove("HeatMap"); this.Elements.Add(newImage); this.Elements.ToHead(newImage); } if (this.gazeDrawingMode == FixationDrawingMode.Spotlight || this.mouseDrawingMode == FixationDrawingMode.Spotlight) { this.Elements.Add(this.spotlightRegion); this.Elements.ToHead(this.spotlightRegion); } }
/////////////////////////////////////////////////////////////////////////////// // Eventhandler // /////////////////////////////////////////////////////////////////////////////// #region EVENTHANDLER /// <summary> /// The <see cref="Form.Load"/> event handler that initializes the UI. /// </summary> /// <param name="sender">Source of the event</param> /// <param name="e">An empty <see cref="EventArgs"/></param> private void VideoPropertiesDialog_Load(object sender, EventArgs e) { // Intialize picture this.picPreview.PresentationSize = this.outputVideoSize; this.ResizeCanvas(); this.gazeVideoRect = new VGImage(this.videoExportProperties.GazeVideoProperties.StreamScreenshot, ImageLayout.Stretch, this.outputVideoSize); this.gazeVideoRect.Name = this.videoExportProperties.GazeVideoProperties.StreamName; this.picPreview.Elements.Add(this.gazeVideoRect); if (File.Exists(this.videoExportProperties.UserVideoProperties.StreamFilename)) { this.userVideoRect = new VGImage(this.videoExportProperties.UserVideoProperties.StreamScreenshot, ImageLayout.Stretch, this.outputVideoSize); this.userVideoRect.Name = this.videoExportProperties.UserVideoProperties.StreamName; this.picPreview.Elements.Add(this.userVideoRect); this.isUserVideoAvailable = true; } else { this.grbUserVideoOptions.Visible = false; this.chbUserVideoVisible.Checked = false; this.isUserVideoAvailable = false; this.grpGazeMouseOptions.Visible = false; this.chbUserVideoVisible.Visible = false; this.label13.Visible = false; } this.PopulateDefaultProperties(); this.UpdatePositionNumerics(); this.isInitializing = false; this.UpdatePreview(); }
/// <summary> /// This static method creates a slide with a sized image /// for each trial and adds it to the slideshow. /// </summary> /// <param name="detectonSettings"> /// The <see cref="DetectionSettings"/> /// used in this import. /// </param> /// <param name="mainWindow"> /// The <see cref="MainForm"/> to get access to the status label. /// </param> public static void GenerateOgamaSlideshowTrials(DetectionSettings detectonSettings, MainForm mainWindow) { // Stores found stimuli files List<string> trialNames = Document.ActiveDocument.ExperimentSettings.SlideShow.GetTrialNames(); foreach (KeyValuePair<int, int> kvp in detectonSettings.TrialSequenceToTrialIDAssignments) { int trialID = kvp.Value; string file = string.Empty; if (detectonSettings.TrialIDToImageAssignments.ContainsKey(trialID)) { file = detectonSettings.TrialIDToImageAssignments[trialID]; } string filename = Path.GetFileNameWithoutExtension(file); // Create slide var stopConditions = new StopConditionCollection { new MouseStopCondition( MouseButtons.Left, true, string.Empty, null, Point.Empty) }; VGImage stimulusImage = null; if (file != string.Empty) { stimulusImage = new VGImage( ShapeDrawAction.None, Pens.Black, Brushes.Black, SystemFonts.MenuFont, Color.White, Path.GetFileName(file), Document.ActiveDocument.ExperimentSettings.SlideResourcesPath, ImageLayout.Zoom, 1f, Document.ActiveDocument.PresentationSize, VGStyleGroup.None, filename, string.Empty, true) { Size = Document.ActiveDocument.PresentationSize }; } var newSlide = new Slide( filename, Color.White, null, stopConditions, null, string.Empty, Document.ActiveDocument.PresentationSize) { Modified = true, MouseCursorVisible = true }; // Only add stimulus if an image exists if (file != string.Empty) { newSlide.VGStimuli.Add(stimulusImage); } else { newSlide.Name = "No stimulus detected"; } // Create trial if (Document.ActiveDocument.ExperimentSettings.SlideShow.GetNodeByID(trialID) != null) { // trialID = int.Parse(Document.ActiveDocument.ExperimentSettings.SlideShow.GetUnusedNodeID()); // var message = string.Format("The trial with the ID:{0} exists already in the slideshow so it will not be created." // + Environment.NewLine + "Delete the trial with this ID in the slideshow design module if you want it to be newly created by the importer, or assign a new ID to the imported data.", trialID); // ExceptionMethods.ProcessMessage("This trial exists already", message); continue; } var newTrial = new Trial(filename, trialID) { Name = filename }; newTrial.Add(newSlide); if (trialNames.Contains(filename) || (filename == string.Empty && trialNames.Contains("No stimulus detected"))) { // Trial already exists continue; } trialNames.Add(filename); // Create slide node var slideNode = new SlideshowTreeNode(newSlide.Name) { Name = trialID.ToString(CultureInfo.InvariantCulture), Slide = newSlide }; // Add slide node to slideshow Document.ActiveDocument.ExperimentSettings.SlideShow.Nodes.Add(slideNode); Document.ActiveDocument.Modified = true; } mainWindow.StatusLabel.Text = "Saving slideshow to file ..."; if (!Document.ActiveDocument.SaveSettingsToFile(Document.ActiveDocument.ExperimentSettings.DocumentFilename)) { ExceptionMethods.ProcessErrorMessage("Couldn't save slideshow to experiment settings."); } mainWindow.StatusLabel.Text = "Refreshing context panel ..."; mainWindow.RefreshContextPanelImageTabs(); mainWindow.StatusLabel.Text = "Ready ..."; mainWindow.StatusProgressbar.Value = 0; }
/////////////////////////////////////////////////////////////////////////////// // Eventhandler // /////////////////////////////////////////////////////////////////////////////// #region EVENTS /////////////////////////////////////////////////////////////////////////////// // Eventhandler for Custom Defined Events // /////////////////////////////////////////////////////////////////////////////// #region CUSTOMEVENTHANDLER #endregion //CUSTOMEVENTHANDLER #endregion //EVENTS /////////////////////////////////////////////////////////////////////////////// // Inherited methods // /////////////////////////////////////////////////////////////////////////////// #region OVERRIDES #endregion //OVERRIDES /////////////////////////////////////////////////////////////////////////////// // Methods for doing main class job // /////////////////////////////////////////////////////////////////////////////// #region METHODS /// <summary> /// This method calculates an heat map out of the /// given channel file and overlays it on the /// background. /// </summary> /// <param name="channelFilename">A <see cref="string"/> with /// filename and full path of the channel image to use.</param> public void VisualizeChannelMapOverlay(string channelFilename) { Bitmap heatMap = AttentionMaps.CreateHeatMapFromBWImage( this.HeatMap, this.ColorMap, this.StimulusSize, channelFilename); VGImage newImage = new VGImage(heatMap, ImageLayout.Center, this.StimulusSize); this.Elements.Clear(); this.Elements.Add(newImage); this.DrawFixationsForCurrentSubject(); this.DrawForeground(true); }
/// <summary> /// Starts new image object by setting the <see cref="VGImage"/> /// in the <see cref="newShape"/> field. /// Then calls <see cref="StartCreation(Cursor)"/>. /// </summary> /// <param name="image">The <see cref="VGImage"/> to be added to the <see cref="Picture"/></param> public void NewImageStart(VGImage image) { switch (image.Layout) { case ImageLayout.Stretch: case ImageLayout.Tile: case ImageLayout.Zoom: case ImageLayout.Center: // In this cases no more drag and pull is needed, // so add the new image to the list. this.Elements.Add(image); // Select it this.SelectedElement = image; break; case ImageLayout.None: // Position and size is needed, so start dragging this.newShape = image; this.StartCreation(CustomCursors.Image); break; } }