How to load an image file in APP DESIGNER

153 views (last 30 days)
I want to load an image form a folder in APP DESIGNER. Below is my code:
classdef Patient1 < matlab.apps.AppBase
% Properties that correspond to app components
properties (Access = public)
UIFigure matlab.ui.Figure
BrainDemoPanel matlab.ui.container.Panel
ImagePanel matlab.ui.container.Panel
Image matlab.ui.control.Image
BrainViewButton matlab.ui.control.Button
BloodViewButton matlab.ui.control.Button
VentriclesViewButton matlab.ui.control.Button
Image_2 matlab.ui.control.Image
TissueViewButton matlab.ui.control.Button
InfoPanel matlab.ui.container.Panel
PatientNameEditFieldLabel matlab.ui.control.Label
PatientNameEditField matlab.ui.control.EditField
OptionPanel matlab.ui.container.Panel
OpenButton matlab.ui.control.Button
FlipButton matlab.ui.control.Button
RunButton matlab.ui.control.Button
EditingPanel matlab.ui.container.Panel
CorrectionButton matlab.ui.control.Button
CleaningtoolforBloodButton matlab.ui.control.Button
CleaningToolforVentriclesButton matlab.ui.control.Button
CleaningToolforCalcificationButton matlab.ui.control.Button
BloodToolInactiveButton matlab.ui.control.Button
DeleteButton matlab.ui.control.Button
AnalyzePanel matlab.ui.container.Panel
CreateBoundaryButton matlab.ui.control.Button
ICHButton matlab.ui.control.Button
SDHButton matlab.ui.control.Button
IVHButton matlab.ui.control.Button
DataPanel matlab.ui.container.Panel
AddExplanationButton matlab.ui.control.Button
ExportDataButton matlab.ui.control.Button
OpenResultsButton matlab.ui.control.Button
SAHButton matlab.ui.control.Button
MorphologicalOperationsButton matlab.ui.control.Button
UndoButton matlab.ui.control.Button
StartBrainSliceButton matlab.ui.control.Button
FullBrainSliceButton matlab.ui.control.Button
ComputationPanel matlab.ui.container.Panel
AllSlicesPanel matlab.ui.container.Panel
BrainVolumeEditFieldLabel matlab.ui.control.Label
BrainVolumeEditField matlab.ui.control.EditField
BloodVolumeEditFieldLabel matlab.ui.control.Label
BloodVolumeEditField matlab.ui.control.EditField
VentriclesVolumeEditFieldLabel matlab.ui.control.Label
VentriclesVolumeEditField matlab.ui.control.EditField
TissueVolumeEditFieldLabel matlab.ui.control.Label
TissueVolumeEditField matlab.ui.control.EditField
BloodStatsPanel matlab.ui.container.Panel
SAHEditFieldLabel matlab.ui.control.Label
SAHEditField matlab.ui.control.EditField
ICHEditFieldLabel matlab.ui.control.Label
ICHEditField matlab.ui.control.EditField
SDHEditFieldLabel matlab.ui.control.Label
SDHEditField matlab.ui.control.EditField
IVHEditFieldLabel matlab.ui.control.Label
IVHEditField matlab.ui.control.EditField
CurrentSlicePanel matlab.ui.container.Panel
BloodStatsPanel_2 matlab.ui.container.Panel
SAHEditField_2Label matlab.ui.control.Label
SAHEditField_2 matlab.ui.control.EditField
ICHEditField_2Label matlab.ui.control.Label
ICHEditField_2 matlab.ui.control.EditField
SDHEditField_2Label matlab.ui.control.Label
SDHEditField_2 matlab.ui.control.EditField
IVHEditField_2Label matlab.ui.control.Label
IVHEditField_2 matlab.ui.control.EditField
CreateBoundaryStatsPanel matlab.ui.container.Panel
EditField_4 matlab.ui.control.EditField
EditField_5 matlab.ui.control.EditField
EditField_6 matlab.ui.control.EditField
EditField_8 matlab.ui.control.EditField
EditField_9 matlab.ui.control.EditField
EditField_10 matlab.ui.control.EditField
EditField_7 matlab.ui.control.EditField
EditField_3 matlab.ui.control.EditField
EditField_2 matlab.ui.control.EditField
EditField matlab.ui.control.EditField
end
% Callbacks that handle component events
methods (Access = private)
% Button pushed function: OpenButton
function OpenButtonPushed(app, event)
[filename,filepath] = uigetfile({'*,*';'*.jpg';'*.png';'*.bmp';'*.oct'}, 'Select File to Open');
fullname = [filepath, filename];
ImageFile = imread(fullname);
axes(handles.axes1)
imagesc(ImageFile);
set(handles.axes1,'visible','off') %hide the current axes
set(get(handles.axes1,'children'),'visible','off') %hide the current axes contents
axis off;
end
% Button pushed function: FlipButton
function FlipButtonPushed(app, event)
end
% Image clicked function: Image
function ImageClicked(app, event)
end
end
% Component initialization
methods (Access = private)
% Create UIFigure and components
function createComponents(app)
% Create UIFigure and hide until all components are created
app.UIFigure = uifigure('Visible', 'off');
app.UIFigure.Position = [100 100 1282 808];
app.UIFigure.Name = 'UI Figure';
% Create BrainDemoPanel
app.BrainDemoPanel = uipanel(app.UIFigure);
app.BrainDemoPanel.TitlePosition = 'centertop';
app.BrainDemoPanel.Title = 'Brain Demo';
app.BrainDemoPanel.FontWeight = 'bold';
app.BrainDemoPanel.Position = [11 18 1217 783];
% Create ImagePanel
app.ImagePanel = uipanel(app.BrainDemoPanel);
app.ImagePanel.Title = 'Image Panel';
app.ImagePanel.FontWeight = 'bold';
app.ImagePanel.Position = [288 322 913 390];
% Create Image
app.Image = uiimage(app.ImagePanel);
app.Image.ImageClickedFcn = createCallbackFcn(app, @ImageClicked, true);
app.Image.Position = [136 76 356 238];
% Create BrainViewButton
app.BrainViewButton = uibutton(app.ImagePanel, 'push');
app.BrainViewButton.Position = [491 342 100 22];
app.BrainViewButton.Text = 'Brain View';
% Create BloodViewButton
app.BloodViewButton = uibutton(app.ImagePanel, 'push');
app.BloodViewButton.Position = [600 342 100 22];
app.BloodViewButton.Text = 'Blood View';
% Create VentriclesViewButton
app.VentriclesViewButton = uibutton(app.ImagePanel, 'push');
app.VentriclesViewButton.Position = [707 342 100 22];
app.VentriclesViewButton.Text = 'Ventricles View';
% Create TissueViewButton
app.TissueViewButton = uibutton(app.ImagePanel, 'push');
app.TissueViewButton.Position = [813 342 100 22];
app.TissueViewButton.Text = 'Tissue View';
% Create Image_2
app.Image_2 = uiimage(app.ImagePanel);
app.Image_2.Position = [491 76 356 238];
% Create InfoPanel
app.InfoPanel = uipanel(app.BrainDemoPanel);
app.InfoPanel.Title = 'Info';
app.InfoPanel.FontWeight = 'bold';
app.InfoPanel.Position = [8 685 260 67];
% Create PatientNameEditFieldLabel
app.PatientNameEditFieldLabel = uilabel(app.InfoPanel);
app.PatientNameEditFieldLabel.HorizontalAlignment = 'right';
app.PatientNameEditFieldLabel.FontWeight = 'bold';
app.PatientNameEditFieldLabel.Position = [27 15 82 22];
app.PatientNameEditFieldLabel.Text = 'Patient Name';
% Create PatientNameEditField
app.PatientNameEditField = uieditfield(app.InfoPanel, 'text');
app.PatientNameEditField.Position = [116 15 100 22];
% Create OptionPanel
app.OptionPanel = uipanel(app.BrainDemoPanel);
app.OptionPanel.Title = 'Option Panel';
app.OptionPanel.FontWeight = 'bold';
app.OptionPanel.Position = [9 582 260 88];
% Create OpenButton
app.OpenButton = uibutton(app.OptionPanel, 'push');
app.OpenButton.ButtonPushedFcn = createCallbackFcn(app, @OpenButtonPushed, true);
app.OpenButton.Position = [9 41 100 22];
app.OpenButton.Text = 'Open ';
% Create FlipButton
app.FlipButton = uibutton(app.OptionPanel, 'push');
app.FlipButton.ButtonPushedFcn = createCallbackFcn(app, @FlipButtonPushed, true);
app.FlipButton.Position = [115 41 100 22];
app.FlipButton.Text = 'Flip';
% Create RunButton
app.RunButton = uibutton(app.OptionPanel, 'push');
app.RunButton.Position = [62 11 100 22];
app.RunButton.Text = 'Run';
% Create EditingPanel
app.EditingPanel = uipanel(app.BrainDemoPanel);
app.EditingPanel.Title = 'Editing Panel';
app.EditingPanel.FontWeight = 'bold';
app.EditingPanel.Position = [10 314 260 252];
% Create CorrectionButton
app.CorrectionButton = uibutton(app.EditingPanel, 'push');
app.CorrectionButton.Position = [62 208 100 22];
app.CorrectionButton.Text = 'Correction';
% Create CleaningtoolforBloodButton
app.CleaningtoolforBloodButton = uibutton(app.EditingPanel, 'push');
app.CleaningtoolforBloodButton.Position = [44.5 177 137 22];
app.CleaningtoolforBloodButton.Text = 'Cleaning tool for Blood';
% Create CleaningToolforVentriclesButton
app.CleaningToolforVentriclesButton = uibutton(app.EditingPanel, 'push');
app.CleaningToolforVentriclesButton.Position = [32.5 148 161 22];
app.CleaningToolforVentriclesButton.Text = 'Cleaning Tool for Ventricles';
% Create CleaningToolforCalcificationButton
app.CleaningToolforCalcificationButton = uibutton(app.EditingPanel, 'push');
app.CleaningToolforCalcificationButton.Position = [26 119 174 22];
app.CleaningToolforCalcificationButton.Text = 'Cleaning Tool for Calcification';
% Create MorphologicalOperationsButton
app.MorphologicalOperationsButton = uibutton(app.EditingPanel, 'push');
app.MorphologicalOperationsButton.Position = [37 89 152 22];
app.MorphologicalOperationsButton.Text = 'Morphological Operations';
% Create UndoButton
app.UndoButton = uibutton(app.EditingPanel, 'push');
app.UndoButton.Position = [62 63 100 22];
app.UndoButton.Text = 'Undo';
% Create BloodToolInactiveButton
app.BloodToolInactiveButton = uibutton(app.EditingPanel, 'push');
app.BloodToolInactiveButton.Position = [50.5 33 121 22];
app.BloodToolInactiveButton.Text = 'Blood Tool(Inactive)';
% Create DeleteButton
app.DeleteButton = uibutton(app.EditingPanel, 'push');
app.DeleteButton.Position = [62 8 100 22];
app.DeleteButton.Text = 'Delete';
% Create AnalyzePanel
app.AnalyzePanel = uipanel(app.BrainDemoPanel);
app.AnalyzePanel.Title = 'Analyze Panel';
app.AnalyzePanel.FontWeight = 'bold';
app.AnalyzePanel.Position = [11 153 260 154];
% Create CreateBoundaryButton
app.CreateBoundaryButton = uibutton(app.AnalyzePanel, 'push');
app.CreateBoundaryButton.Position = [61 110 106 22];
app.CreateBoundaryButton.Text = 'Create Boundary';
% Create SAHButton
app.SAHButton = uibutton(app.AnalyzePanel, 'push');
app.SAHButton.Position = [61 81 100 22];
app.SAHButton.Text = 'SAH';
% Create ICHButton
app.ICHButton = uibutton(app.AnalyzePanel, 'push');
app.ICHButton.Position = [64 52 100 22];
app.ICHButton.Text = 'ICH';
% Create SDHButton
app.SDHButton = uibutton(app.AnalyzePanel, 'push');
app.SDHButton.Position = [63 23 100 22];
app.SDHButton.Text = 'SDH';
% Create IVHButton
app.IVHButton = uibutton(app.AnalyzePanel, 'push');
app.IVHButton.Position = [64 2 100 22];
app.IVHButton.Text = 'IVH';
% Create DataPanel
app.DataPanel = uipanel(app.BrainDemoPanel);
app.DataPanel.Title = 'Data Panel';
app.DataPanel.FontWeight = 'bold';
app.DataPanel.Position = [8 67 260 79];
% Create AddExplanationButton
app.AddExplanationButton = uibutton(app.DataPanel, 'push');
app.AddExplanationButton.Position = [66 34 103 22];
app.AddExplanationButton.Text = 'Add Explanation';
% Create ExportDataButton
app.ExportDataButton = uibutton(app.DataPanel, 'push');
app.ExportDataButton.Position = [70 5 100 22];
app.ExportDataButton.Text = 'Export Data';
% Create OpenResultsButton
app.OpenResultsButton = uibutton(app.BrainDemoPanel, 'push');
app.OpenResultsButton.Position = [72 35 100 22];
app.OpenResultsButton.Text = 'Open Results';
% Create StartBrainSliceButton
app.StartBrainSliceButton = uibutton(app.BrainDemoPanel, 'push');
app.StartBrainSliceButton.Position = [343 293 100 22];
app.StartBrainSliceButton.Text = 'StartBrainSlice';
% Create FullBrainSliceButton
app.FullBrainSliceButton = uibutton(app.BrainDemoPanel, 'push');
app.FullBrainSliceButton.Position = [645 293 100 22];
app.FullBrainSliceButton.Text = 'FullBrainSlice';
% Create EditField
app.EditField = uieditfield(app.BrainDemoPanel, 'text');
app.EditField.Position = [455 293 100 22];
% Create EditField_2
app.EditField_2 = uieditfield(app.BrainDemoPanel, 'text');
app.EditField_2.Position = [758 293 100 22];
% Create ComputationPanel
app.ComputationPanel = uipanel(app.BrainDemoPanel);
app.ComputationPanel.Title = 'Computation Panel';
app.ComputationPanel.FontWeight = 'bold';
app.ComputationPanel.Position = [288 15 913 273];
% Create AllSlicesPanel
app.AllSlicesPanel = uipanel(app.ComputationPanel);
app.AllSlicesPanel.Title = 'All Slices';
app.AllSlicesPanel.Position = [55 20 455 221];
% Create BrainVolumeEditFieldLabel
app.BrainVolumeEditFieldLabel = uilabel(app.AllSlicesPanel);
app.BrainVolumeEditFieldLabel.HorizontalAlignment = 'right';
app.BrainVolumeEditFieldLabel.Position = [-2 170 77 22];
app.BrainVolumeEditFieldLabel.Text = 'Brain Volume';
% Create BrainVolumeEditField
app.BrainVolumeEditField = uieditfield(app.AllSlicesPanel, 'text');
app.BrainVolumeEditField.Position = [90 170 100 22];
% Create BloodVolumeEditFieldLabel
app.BloodVolumeEditFieldLabel = uilabel(app.AllSlicesPanel);
app.BloodVolumeEditFieldLabel.HorizontalAlignment = 'right';
app.BloodVolumeEditFieldLabel.Position = [-5 141 80 22];
app.BloodVolumeEditFieldLabel.Text = 'Blood Volume';
% Create BloodVolumeEditField
app.BloodVolumeEditField = uieditfield(app.AllSlicesPanel, 'text');
app.BloodVolumeEditField.Position = [90 141 100 22];
% Create VentriclesVolumeEditFieldLabel
app.VentriclesVolumeEditFieldLabel = uilabel(app.AllSlicesPanel);
app.VentriclesVolumeEditFieldLabel.HorizontalAlignment = 'right';
app.VentriclesVolumeEditFieldLabel.Position = [-2 110 101 22];
app.VentriclesVolumeEditFieldLabel.Text = 'Ventricles Volume';
% Create VentriclesVolumeEditField
app.VentriclesVolumeEditField = uieditfield(app.AllSlicesPanel, 'text');
app.VentriclesVolumeEditField.Position = [114 110 100 22];
% Create TissueVolumeEditFieldLabel
app.TissueVolumeEditFieldLabel = uilabel(app.AllSlicesPanel);
app.TissueVolumeEditFieldLabel.HorizontalAlignment = 'right';
app.TissueVolumeEditFieldLabel.Position = [6 77 84 22];
app.TissueVolumeEditFieldLabel.Text = 'Tissue Volume';
% Create TissueVolumeEditField
app.TissueVolumeEditField = uieditfield(app.AllSlicesPanel, 'text');
app.TissueVolumeEditField.Position = [105 77 100 22];
% Create BloodStatsPanel
app.BloodStatsPanel = uipanel(app.AllSlicesPanel);
app.BloodStatsPanel.Title = 'Blood Stats';
app.BloodStatsPanel.Position = [222 32 215 160];
% Create SAHEditFieldLabel
app.SAHEditFieldLabel = uilabel(app.BloodStatsPanel);
app.SAHEditFieldLabel.HorizontalAlignment = 'right';
app.SAHEditFieldLabel.Position = [43 109 30 22];
app.SAHEditFieldLabel.Text = 'SAH';
% Create SAHEditField
app.SAHEditField = uieditfield(app.BloodStatsPanel, 'text');
app.SAHEditField.Position = [88 109 100 22];
% Create ICHEditFieldLabel
app.ICHEditFieldLabel = uilabel(app.BloodStatsPanel);
app.ICHEditFieldLabel.HorizontalAlignment = 'right';
app.ICHEditFieldLabel.Position = [47 78 26 22];
app.ICHEditFieldLabel.Text = 'ICH';
% Create ICHEditField
app.ICHEditField = uieditfield(app.BloodStatsPanel, 'text');
app.ICHEditField.Position = [88 78 100 22];
% Create SDHEditFieldLabel
app.SDHEditFieldLabel = uilabel(app.BloodStatsPanel);
app.SDHEditFieldLabel.HorizontalAlignment = 'right';
app.SDHEditFieldLabel.Position = [42 45 31 22];
app.SDHEditFieldLabel.Text = 'SDH';
% Create SDHEditField
app.SDHEditField = uieditfield(app.BloodStatsPanel, 'text');
app.SDHEditField.Position = [88 45 100 22];
% Create IVHEditFieldLabel
app.IVHEditFieldLabel = uilabel(app.BloodStatsPanel);
app.IVHEditFieldLabel.HorizontalAlignment = 'right';
app.IVHEditFieldLabel.Position = [48 13 26 22];
app.IVHEditFieldLabel.Text = 'IVH';
% Create IVHEditField
app.IVHEditField = uieditfield(app.BloodStatsPanel, 'text');
app.IVHEditField.Position = [89 13 100 22];
% Create CurrentSlicePanel
app.CurrentSlicePanel = uipanel(app.ComputationPanel);
app.CurrentSlicePanel.Title = 'Current Slice';
app.CurrentSlicePanel.Position = [528 12 376 229];
% Create BloodStatsPanel_2
app.BloodStatsPanel_2 = uipanel(app.CurrentSlicePanel);
app.BloodStatsPanel_2.Title = 'Blood Stats';
app.BloodStatsPanel_2.Position = [56 29 180 178];
% Create SAHEditField_2Label
app.SAHEditField_2Label = uilabel(app.BloodStatsPanel_2);
app.SAHEditField_2Label.HorizontalAlignment = 'right';
app.SAHEditField_2Label.Position = [26 120 30 22];
app.SAHEditField_2Label.Text = 'SAH';
% Create SAHEditField_2
app.SAHEditField_2 = uieditfield(app.BloodStatsPanel_2, 'text');
app.SAHEditField_2.Position = [71 120 100 22];
% Create ICHEditField_2Label
app.ICHEditField_2Label = uilabel(app.BloodStatsPanel_2);
app.ICHEditField_2Label.HorizontalAlignment = 'right';
app.ICHEditField_2Label.Position = [31 89 26 22];
app.ICHEditField_2Label.Text = 'ICH';
% Create ICHEditField_2
app.ICHEditField_2 = uieditfield(app.BloodStatsPanel_2, 'text');
app.ICHEditField_2.Position = [72 89 100 22];
% Create SDHEditField_2Label
app.SDHEditField_2Label = uilabel(app.BloodStatsPanel_2);
app.SDHEditField_2Label.HorizontalAlignment = 'right';
app.SDHEditField_2Label.Position = [26 56 31 22];
app.SDHEditField_2Label.Text = 'SDH';
% Create SDHEditField_2
app.SDHEditField_2 = uieditfield(app.BloodStatsPanel_2, 'text');
app.SDHEditField_2.Position = [72 56 100 22];
% Create IVHEditField_2Label
app.IVHEditField_2Label = uilabel(app.BloodStatsPanel_2);
app.IVHEditField_2Label.HorizontalAlignment = 'right';
app.IVHEditField_2Label.Position = [31 24 26 22];
app.IVHEditField_2Label.Text = 'IVH';
% Create IVHEditField_2
app.IVHEditField_2 = uieditfield(app.BloodStatsPanel_2, 'text');
app.IVHEditField_2.Position = [72 24 100 22];
% Create CreateBoundaryStatsPanel
app.CreateBoundaryStatsPanel = uipanel(app.CurrentSlicePanel);
app.CreateBoundaryStatsPanel.Title = 'Create Boundary Stats';
app.CreateBoundaryStatsPanel.Position = [235 53 128 147];
% Create EditField_3
app.EditField_3 = uieditfield(app.CreateBoundaryStatsPanel, 'text');
app.EditField_3.Position = [13 103 100 22];
% Create EditField_4
app.EditField_4 = uieditfield(app.CreateBoundaryStatsPanel, 'text');
app.EditField_4.Position = [14 75 100 22];
% Create EditField_5
app.EditField_5 = uieditfield(app.CreateBoundaryStatsPanel, 'text');
app.EditField_5.Position = [14 44 100 22];
% Create EditField_6
app.EditField_6 = uieditfield(app.CreateBoundaryStatsPanel, 'text');
app.EditField_6.Position = [13 15 100 22];
% Create EditField_7
app.EditField_7 = uieditfield(app.CurrentSlicePanel, 'text');
app.EditField_7.Position = [9 156 33 22];
% Create EditField_8
app.EditField_8 = uieditfield(app.CurrentSlicePanel, 'text');
app.EditField_8.Position = [9 128 33 22];
% Create EditField_9
app.EditField_9 = uieditfield(app.CurrentSlicePanel, 'text');
app.EditField_9.Position = [9 97 33 22];
% Create EditField_10
app.EditField_10 = uieditfield(app.CurrentSlicePanel, 'text');
app.EditField_10.Position = [9 68 33 22];
% Show the figure after all components are created
app.UIFigure.Visible = 'on';
end
end
% App creation and deletion
methods (Access = public)
% Construct app
function app = Patient1
% Create UIFigure and components
createComponents(app)
% Register the app with App Designer
registerApp(app, app.UIFigure)
if nargout == 0
clear app
end
end
% Code that executes before app deletion
function delete(app)
% Delete UIFigure when app is deleted
delete(app.UIFigure)
end
end
end
However, I am getting the following error message.
Undefined variable "handles" or class "handles.axes1".
Error in Patient1/OpenButtonPushed (line 92)
axes(handles.axes1)
Error using matlab.ui.control.internal.controller.ComponentController/executeUserCallback (line 335)
Error while evaluating Button PrivateButtonPushedFcn.
Any help would be appreciated.

Accepted Answer

Kojiro Saito
Kojiro Saito on 21 Jun 2019
You need create uiaxes first and show the image on the axes.
First, add Axes component in Design View of App Designer. UIAxes will be added automatically.
% Properties that correspond to app components
properties (Access = public)
UIFigure matlab.ui.Figure
UIAxes matlab.ui.control.UIAxes
% ...
end
Next, uncheck Visible from INTERACTIVITY of app.UIAxes from Inspector pane.
2019621104136.jpg
Then, do imagesc or imshow by spcifying app.UIAxes.
% Button pushed function: OpenButton
function OpenButtonPushed(app, event)
[filename,filepath] = uigetfile({'*.*;*.jpg;*.png;*.bmp;*.oct'}, 'Select File to Open');
fullname = [filepath, filename];
ImageFile = imread(fullname);
imagesc(app.UIAxes, ImageFile);
end
  7 Comments
Walter Roberson
Walter Roberson on 22 Jun 2019
" is there any reason you should use imagesc?"
Perhaps because using imshow() should be confined to the command line and very short exploration scripts, and not used serious programming? imshow() does not just resize the figure, it deletes the axes whenever it can.

Sign in to comment.

More Answers (1)

Mataramasuko Abdülhakim
Mataramasuko Abdülhakim on 8 May 2020
Well if you had only put the relevant code first, then all code I would of help but this is too complicated. You should of highlight the part for us to see.

Categories

Find more on Labels and Annotations in Help Center and File Exchange

Products


Release

R2019a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!