Main Content

Create an App to Measure Images Using Edge‑Snapping Metrology

R2026b
Since R2026b

This example shows how to build an app to interactively measure images with edge snapping measurement functions using App Designer. Using the EdgeSnappingMeasurementApp app, users can draw multiple measurements of different types directly on the image and export the measurements to the workspace. The app supports these measurement functions:

  • uicaliper — Measures distance between two points and reports inter‑edge and intra‑edge distances where edges are detected along the caliper profile. In the EdgeSnappingMeasurementApp app, the start and end points can snap to edges near the drawing area to provide a more accurate measurement.

  • uitsquare — Measures one or more perpendicular distances from a reference T‑square edge. In the EdgeSnappingMeasurementApp app, the T-square edge and measurement lines can snap to edges near the drawing area to provide a more accurate measurement.

  • uifitangle — Measures the angle formed by three points. In the EdgeSnappingMeasurementApp app, the angle edges and points can snap to edges near the drawing area to provide a more accurate measurement.

  • uifitcircle — Measures circle properties such as radius, area, and circumference. In the EdgeSnappingMeasurementApp app, the circle annotation input can snap to circles near the drawing area to provide a more accurate measurement.

Open App Designer

App Designer is an interactive development environment for designing apps and custom UI components and programming their behavior.

To build the app from scratch, open App Designer using this command. Alternatively, you can open App Designer by selecting the Design App option on the Apps tab of the MATLAB® toolstrip.

appdesigner

The EdgeSnappingMeasurementApp app is also attached to this example as a supporting file. For information on running the app, see the Measure an Image Using App section.

You can also open this example from the App Designer home page by clicking Show examples in the Apps section of the home page and selecting Measure with Edge Snapping Tool from the list of examples.

You can customize the code of the app in the attached supporting files. For information on customizing the app, see the Customize the App section.

App Layout Design

The EdgeSnappingMeasurementApp app has two main regions: a toolstrip and a working area.

The toolstrip contains these sections:

  • Import — Consists of UI components used to import an image from a file or the workspace.

  • Controls — Consists of UI components used to specify pixel extent, enable edge snapping, start a new measurement, or delete existing measurements.

  • Export — Consists of UI components used to export the measurements to the workspace.

The working area of the app contains these sections:

  • Viewer — Displays the imported image. The app displays the image using the imageshow function. The handle of the displayed image is an Image object. A Viewer object is the parent of the Image object. For more information about the Image object, see Image Properties. For more information about the Viewer object, see Viewer Properties.

  • Measurement Parameters and History — Contains tabs for each type of measurement, and displays a tabular list of measurements of the corresponding type in each tab. Each row contains the parameters of a measurement and a check box to select the measurement for deletion.

App layout.

The app uses a grid layout structure to create the defined layout.

  • Main App figure

    • Main app grid layout

      • Toolstrip grid layout

        • Toolstrip elements like import, controls, export

      • Working area grid layout

        • Image panel containing Image object

        • Measurement parameters and history

          • Tabs for each type of measurement containing tabular list of measurements of that type

For more information on using grid layout with App Designer, see Use Grid Layout Managers in App Designer.

Define App Properties

The app stores the input image and measurements in these properties.

  • Viewer — Viewer object used to display the image.

  • ImageHandle — Image object created by imageshow, used to display and update the loaded image.

  • CaliperMeasurementControlRows — Structure array to store the properties of a caliper measurement object. Users can change the properties of a caliper measurement even after drawing it.

  • TSquareMeasurementControlRows — Structure array to store the properties of a T-square measurement object. Users can change only the color of the T-square measurement after drawing it.

  • AngleMeasurementControlRows — Structure array to store the properties of an angle measurement object. Users can change only the color of the angle measurement after drawing it.

  • CircleMeasurementControlRows — Structure array to store the properties of a circle measurement object. Users can change only the color of the circle measurement after drawing it.

Define App Methods

The app uses methods to import and visualize data, process user input, export the final results, and control the app state. The app also uses some helper functions to improve code readability and code reusability. These are some of the important app methods.

Reset App on New Data Load

When the user loads a new image into the app, the app clears the existing image data, displays the loaded image, and clears all measurement history. The app resets UI elements to their default states and enables the drop-down used to select a measurement type. The resetAppOnNewDataLoad method defines this behavior.

function resetAppOnNewDataLoad(app,imageData)
    % Function to reset app when new data is loaded

    % Set the newly loaded image data and reset viewer2d.
    app.ImageHandle.Data = imageData;
    app.Viewer.Interactions = ["pan","zoom"];
    micrometersPerPixel = app.PixelExtentEditField.Value;
    unitSpec = imref2d(size(imageData),micrometersPerPixel,micrometersPerPixel);
    app.ImageHandle.Transformation = unitSpec;

    % Reset UI elements to default state
    app.MeasureDropDownLabel.Enable = "on";
    app.MeasureDropDown.Enable = "on";
    app.EdgeSnappingSwitch.Enable = "on";
    app.PixelExtentEditFieldLabel.Enable = "on";
    app.PixelExtentEditField.Enable = "on";
    app.ExportButton.Enable = "off";
    app.DeleteButton.Enable = "off";

    % Clear existing caliper measurements
    for idx = 1:length(app.CaliperMeasurementControlRows)
        caliperMeasurementControlRow = app.CaliperMeasurementControlRows(idx);
        fields = fieldnames(caliperMeasurementControlRow);
        for j = 1:numel(fields)
            if ~ismember(fields{j},"ID")
                delete(caliperMeasurementControlRow.(fields{j}));
            end
        end
    end
    app.CaliperMeasurementControlRows(1:end) = [];

    % Clear existing T-square measurements
    for idx = 1:length(app.TSquareMeasurementControlRows)
        tsquareMeasurementControlRow = app.TSquareMeasurementControlRows(idx);
        fields = fieldnames(tsquareMeasurementControlRow);
        for j = 1:numel(fields)
            if ~ismember(fields{j},"ID")
                delete(tsquareMeasurementControlRow.(fields{j}));
            end
        end
    end
    app.TSquareMeasurementControlRows(1:end) = [];

    % Clear existing angle measurements
    for idx = 1:length(app.AngleMeasurementControlRows)
        angleMeasurementControlRow = app.AngleMeasurementControlRows(idx);
        fields = fieldnames(angleMeasurementControlRow);
        for j = 1:numel(fields)
            if ~ismember(fields{j},"ID")
                delete(angleMeasurementControlRow.(fields{j}));
            end
        end
    end
    app.AngleMeasurementControlRows(1:end) = [];

    % Clear existing circle measurements
    for idx = 1:length(app.CircleMeasurementControlRows)
        circleMeasurementControlRow = app.CircleMeasurementControlRows(idx);
        fields = fieldnames(circleMeasurementControlRow);
        for j = 1:numel(fields)
            if ~ismember(fields{j},"ID")
                delete(circleMeasurementControlRow.(fields{j}));
            end
        end
    end
    app.CircleMeasurementControlRows(1:end) = [];
end

Set Pixel Extent

To improve measurement accuracy, the app enables you to specify a Pixel Extent value, in micrometers per pixel, which it uses to create a 2‑D spatial referencing object with imref2d. The app assigns that object to the Transformation property of the Image object so that measurements use the specified world scale. The PixelExtentEditFieldValueChanged method defines this behavior.

function PixelExtentEditFieldValueChanged(app,event)
    % Callback function to update pixel extent based on user input
    micrometersPerPixel = app.PixelExtentEditField.Value;
    unitSpec = imref2d(size(app.ImageHandle.Data),micrometersPerPixel,micrometersPerPixel);
    app.ImageHandle.Transformation = unitSpec;
end

Add New Measurement

When the user selects a new measurement from the Measure drop-down in the Controls section of the app toolstrip, the app switches to the corresponding tab in the Measurement Parameters and History section. The app adds a new row of UI controls at the top of that tab for parameter input. Each row starts with a check box, used later for selecting rows to delete, followed by controls for tool parameters such as width, snap neighborhood, and edge map. The MeasureDropDownValueChanged method defines this behavior.

% Value changed function: MeasureDropDown
function MeasureDropDownValueChanged(app,event)
    % Callback function for processing user
    % measurement selection  

    % Once the first measurement is added, pixel extent can no
    % longer be modified.
    app.PixelExtentEditField.Enable = "off";
    app.PixelExtentEditFieldLabel.Enable = "off";

    value = app.MeasureDropDown.Value;
    % If user did not select one of these measurements, then
    % do nothing
    if ~ismember(value,["Caliper","T-Square","Angle","Circle"])
        return;
    end
    % Lock all existing control inputs
    app.disableForControlInput();
    % Switch to the selected measurement tab and create a new row
    % for input
    switch value
        case "Caliper"
            app.TabGroup.SelectedTab = app.Caliper;
            app.addNewCaliperMeasurementControlRow();
        case "T-Square"
            app.TabGroup.SelectedTab = app.T_Square;
            app.addNewTSquareMeasurementControlRow();
        case "Angle"
            app.TabGroup.SelectedTab = app.Angle;
            app.addNewAngleMeasurementControlRow();
        case "Circle"
            app.TabGroup.SelectedTab = app.Circle;
            app.addNewCircleMeasurementControlRow();
    end
end

Create Measurement Annotation in Draw Mode

After the user selects a new measurement and specifies the measurement parameters, they can select the Draw option in the Controls section of the app toolstrip to enter the drawing mode of the app. The app locks most app controls while in drawing mode to ensure that the app state does not change in the middle of an interaction. The app reads the parameter values from the latest row added to the corresponding measurement tab and calls the appropriate interactive metrology function. Once the user has finished drawing, the app re‑enables the parameter fields that are editable after drawing. For example, the Color parameter is editable after drawing any measurement annotation, but the Snap parameter is not editable for caliper annotations. The DrawButtonPushed method defines this behavior.

% Button pushed function: DrawButton
function DrawButtonPushed(app,event)
    % Callback function to process the current measurement inputs
    % and start drawing

    selectedMeasurementTool = app.MeasureDropDown.Value;

    % Reset the selection back to default
    app.MeasureDropDown.Value = app.MeasureDropDown.Items(1);
    % Lock draw button until user re-selects a measurement
    app.DrawButton.Enable = "off";
    app.CancelButton.Enable = "off";

    % Enable drawing of the selected measurement with control inputs
    % provided by user. Also lock the last created row of controls
    switch selectedMeasurementTool
        case "Caliper"
            parameters = app.CaliperMeasurementControlRows(end);

            % Lock last caliper input
            fields = fieldnames(parameters);
            for j = 1:numel(fields)
                if ~ismember(fields{j},["ID","Annotation"])
                    parameters.(fields{j}).Enable = false;
                end
            end

            % Switch to drawing caliper measurement
            hcaliper = uicaliper(app.ImageHandle, ...
                Width=parameters.Width.Value, ...
                Color=parameters.Color.Value, ...
                EdgeTransition=parameters.EdgeTransition.Value, ...
                GradientThreshold=parameters.GradientThreshold.Value, ...
                Sigma=parameters.SigmaEditField.Value, ...
                MeasurementMode=parameters.MeasurementMode.Value, ...
                DisplayProfile=parameters.DisplayProfile.Value);
            app.CaliperMeasurementControlRows(end).Annotation = hcaliper;
        case "T-Square"
            parameters = app.TSquareMeasurementControlRows(end);

            % Lock last T-square input
            fields = fieldnames(parameters);
            for j = 1:numel(fields)
                if ~ismember(fields{j},["ID","Annotation"])
                    parameters.(fields{j}).Enable = false;
                end
            end

            % Switch to drawing t-square measurement
            htsquare = uitsquare(app.ImageHandle, ...
                SnapNeighborhood=parameters.SnapNeighborhood.Value, ...
                Color=parameters.Color.Value, ...
                PointSnapMethod=parameters.PointSnapMethod.Value, ...
                LineSnapMethod=parameters.LineSnapMethod.Value, ...
                EdgeMap=string(parameters.EdgeMap.Value));
            app.TSquareMeasurementControlRows(end).Annotation = htsquare;
        case "Angle"
            parameters = app.AngleMeasurementControlRows(end);

            % Lock last angle input
            fields = fieldnames(parameters);
            for j = 1:numel(fields)
                if ~ismember(fields{j},["ID","Annotation"])
                    parameters.(fields{j}).Enable = false;
                end
            end

            % Switch to drawing angle measurement
            hangle = uifitangle(app.ImageHandle, ...
                Color=parameters.Color.Value, ...
                Snap=parameters.Snap.Value, ...
                SnapNeighborhood=parameters.SnapNeighborhood.Value, ...
                LineSnapMethod=parameters.LineSnapMethod.Value, ...
                PointSnapMethod=parameters.PointSnapMethod.Value, ...
                EdgeMap=string(parameters.EdgeMap.Value));
            app.AngleMeasurementControlRows(end).Annotation = hangle;
        case "Circle"
            parameters = app.CircleMeasurementControlRows(end);

            % If angle range is not strictly increasing, show error
            % and revert back to input mode.
            if parameters.AngleRangeMin.Value >= parameters.AngleRangeMax.Value
                uialert(app.EdgeSnappingMeasurementToolFigure, ...
                    "Expected angle range to be strictly increasing.", ...
                    "Input error");
                app.MeasureDropDown.Value = "Circle";
                app.DrawButton.Enable = "on";
                app.CancelButton.Enable = "on";
                return;
            end

            % Lock last circle input
            fields = fieldnames(parameters);
            for j = 1:numel(fields)
                if ~ismember(fields{j},["ID","Annotation"])
                    parameters.(fields{j}).Enable = false;
                end
            end

            % Switch to drawing circle measurement
            hcircle = uifitcircle(app.ImageHandle, ...
                Snap=parameters.Snap.Value, ...
                Color=parameters.Color.Value, ...
                SnapNeighborhood=parameters.SnapNeighborhood.Value, ...
                RansacIterations=parameters.RansacIterations.Value, ...
                RansacInlierDistance=parameters.RansacInlierDistance.Value, ...
                AngleRange=[parameters.AngleRangeMin.Value parameters.AngleRangeMax.Value], ...
                EdgeMap=string(parameters.EdgeMap.Value));
            app.CircleMeasurementControlRows(end).Annotation = hcircle;
    end
    % Once drawing is completed, re-enable all editable inputs
    app.enableAfterControlInput();
end

Change Parameters After Measurement

Users can change some measurement parameters even after drawing. The app links each row of the measurement history to its corresponding measurement annotation using a universally unique identifier (UUID). The app matches any changes in the parameters to the measurement annotation using this UUID. The measurementControlValueChanged method defines this behavior.

function measurementControlValueChanged(app,evt,measurementType,propertyName,id)
    % Callback function for processing user inputs after drawing is
    % completed. When user updates any of the editable properties of
    % any measurement, this function passes them to the
    % measurement handle
    switch measurementType
        case "Caliper"
            index = ismember([app.CaliperMeasurementControlRows.ID],id);
            if ~isempty(app.CaliperMeasurementControlRows(index).Annotation)
                app.CaliperMeasurementControlRows(index).Annotation.(propertyName) = evt.Value;
            end
        case "T-Square"
            index = ismember([app.TSquareMeasurementControlRows.ID],id);
            if ~isempty(app.TSquareMeasurementControlRows(index).Annotation)
                app.TSquareMeasurementControlRows(index).Annotation.(propertyName) = evt.Value;
            end
        case "Angle"
            index = ismember([app.AngleMeasurementControlRows.ID],id);
            if ~isempty(app.AngleMeasurementControlRows(index).Annotation)
                app.AngleMeasurementControlRows(index).Annotation.(propertyName) = evt.Value;
            end
        case "Circle"
            index = ismember([app.CircleMeasurementControlRows.ID],id);
            if ~isempty(app.CircleMeasurementControlRows(index).Annotation)
                app.CircleMeasurementControlRows(index).Annotation.(propertyName) = evt.Value;
            end
    end
end

Delete Multiple Measurements

Users can delete multiple measurements simultaneously by selecting one or more rows in the measurement history using the corresponding check boxes in the first column and then selecting Delete in the Controls section of the app toolstrip. The app enables the Delete button only when at least one measurement has been selected. The DeleteButtonPushed method calls the deletion functions specific to each type of measurement. Each deletion function uses the index and UUIDs of the selected measurements in the corresponding tab to delete the measurement annotation from the Viewer section, delete the measurement row from the measurement history, and move the remaining rows upward. For example, the deleteSelectedCaliper function deletes all selected measurements in the Caliper tab of the measurement history.

% Button pushed function: DeleteButton
function DeleteButtonPushed(app,event)
    % Callback function to delete selected rows of measurements
    app.deleteSelectedCaliper();
    app.deleteSelectedTsquare();
    app.deleteSelectedAngle();
    app.deleteSelectedCircle();

    app.DeleteButton.Enable = "off";

    % If all measurements are deleted, lock the export button
    if isempty(app.CaliperMeasurementControlRows) && isempty(app.TSquareMeasurementControlRows) && isempty(app.AngleMeasurementControlRows) && isempty(app.CircleMeasurementControlRows)
        app.ExportButton.Enable = "off";
    end
end

function deleteSelectedCaliper(app)
    % Helper function to delete all selected rows of caliper
    % measurements

    % Find the selected rows of caliper measurements
    deletedIndex = false(1,length(app.CaliperMeasurementControlRows));
    for idx = 1:length(app.CaliperMeasurementControlRows)
        caliperMeasurementControlRow = app.CaliperMeasurementControlRows(idx);
        if caliperMeasurementControlRow.Select.Value
            deletedIndex(idx) = true;
            fields = fieldnames(caliperMeasurementControlRow);
            % Delete the UI elements of the selected rows
            for j = 1:numel(fields)
                if ~ismember(fields{j},"ID")
                    delete(caliperMeasurementControlRow.(fields{j}));
                end
            end
        end
    end
    % If any row of caliper measurement was selected, remove it from
    % CaliperMeasurementControlRows and move the remaining rows up
    % to use the empty fields
    if any(deletedIndex)
        app.CaliperMeasurementControlRows(deletedIndex) = [];
        for idx = 1:length(app.CaliperMeasurementControlRows)
            caliperMeasurementControlRow = app.CaliperMeasurementControlRows(idx);
            caliperMeasurementControlRow.Select.Parent.Layout.Row = idx + 1;
        end
    end
end

Export All Measurements

When the user selects the Export option, the app collects the measurement results in the current state into a single structure named Measurements and exports it to the base workspace. The structure contains one array for each measurement type. The app exports these measurement details for each type of measurement.

The app then shows a success dialog after exporting. The ExportButtonPushed method defines this behavior.

% Button pushed function: ExportButton
function ExportButtonPushed(app,event)
    % Callback function to gather all measurement results and write
    % it to workspace
    Measurements = struct();

    % Gather InterEdgeDistance, IntraEdgeDistance, Distance and
    % GradientValue fields of caliper measurements to write in export
    caliperAnnotations = struct("InterEdgeDistance",{},"IntraEdgeDistance",{},"Distance",{},"GradientValue",{});
    for idx = 1:length(app.CaliperMeasurementControlRows)
        caliperMeasurementControlRow = app.CaliperMeasurementControlRows(idx);

        caliperResult.InterEdgeDistance = caliperMeasurementControlRow.Annotation.InterEdgeDistance;
        caliperResult.IntraEdgeDistance = caliperMeasurementControlRow.Annotation.IntraEdgeDistance;
        caliperResult.Distance = caliperMeasurementControlRow.Annotation.Distance;
        caliperResult.GradientValue = caliperMeasurementControlRow.Annotation.GradientValue;

        caliperAnnotations(idx) = caliperResult;
    end
    Measurements.CaliperAnnotation = caliperAnnotations;

    % Gather Distance, Position, ReferenceLine and
    % MeasurementPoints fields of T-square measurements to write in export
    tsquareAnnotations = struct("Distance",{},"Position",{},"ReferenceLine",{},"MeasurementPoints",{});
    for idx = 1:length(app.TSquareMeasurementControlRows)
        tSquareMeasurementControlRow = app.TSquareMeasurementControlRows(idx);

        tsquareResult.Distance = tSquareMeasurementControlRow.Annotation.Distance;
        tsquareResult.Position = tSquareMeasurementControlRow.Annotation.Position;
        tsquareResult.ReferenceLine = tSquareMeasurementControlRow.Annotation.ReferenceLine;
        tsquareResult.MeasurementPoints = tSquareMeasurementControlRow.Annotation.MeasurementPoints;

        tsquareAnnotations(idx) = tsquareResult;
    end
    Measurements.TSquareAnnotation = tsquareAnnotations;

    % Gather Position and Theta fields of angle measurements to
    % write in export
    angleAnnotations = struct("Position",{},"Theta",{});
    for idx = 1:length(app.AngleMeasurementControlRows)
        angleMeasurementControlRow = app.AngleMeasurementControlRows(idx);

        angleResult.Position = angleMeasurementControlRow.Annotation.Position;
        angleResult.Theta = angleMeasurementControlRow.Annotation.Theta;

        angleAnnotations(idx) = angleResult;
    end
    Measurements.AngleAnnotation = angleAnnotations;

    % Gather Center, Radius, Area and Circumference fields of circle
    % measurements to write in export
    circleAnnotations = struct("Center",{},"Radius",{},"Area",{},"Circumference",{});
    for idx = 1:length(app.CircleMeasurementControlRows)
        circleMeasurementControlRow = app.CircleMeasurementControlRows(idx);

        circleResult.Center = circleMeasurementControlRow.Annotation.Center;
        circleResult.Radius = circleMeasurementControlRow.Annotation.Radius;
        circleResult.Area = circleMeasurementControlRow.Annotation.Area;
        circleResult.Circumference = circleMeasurementControlRow.Annotation.Circumference;

        circleAnnotations(idx) = circleResult;
    end
    Measurements.CircleAnnotation = circleAnnotations;

    % Write Measurements to base workspace
    assignin("base","Measurements",Measurements);
    uialert(app.EdgeSnappingMeasurementToolFigure, ...
        "Measurements saved to workspace successfully", ...
        "Export Success", ...
        Icon="success");
end

Measure an Image Using App

Run the EdgeSnappingMeasurementApp app.

Import an image either from a file or from the workspace using the options in the Import section of the app toolstrip. If you choose to import the image from a file, the app opens a dialog box enabling you to browse files that have image file formats. If you choose to import the image from the workspace, the app filters workspace variables for potential images and displays the variable names in the drop-down. When you import an image, the app resets and displays the imported image in the Viewer section of the app.

To measure using the caliper measurement, perform these steps.

  1. From the Measure drop-down in the Controls section of the app toolstrip, select Caliper. Ensure edge-snapping is enabled for more accurate measurement.

  2. In the Measurement Parameters and History section, the Caliper tab is active. Specify the desired parameters for the measurement in the Caliper tab.

  3. Select Draw in the Controls section of the app toolstrip. To cancel drawing and start a new measurement, select Cancel.

  4. Select two points on the image in the Viewer section to measure the distance, inter-edge distance, and intra-edge distance.

  5. Right-click to complete the measurement and exit the drawing mode.

Caliper measurement in the app

To measure using the T-square measurement, perform these steps.

  1. From the Measure drop-down in the Controls section of the app toolstrip, select T-Square. Ensure edge-snapping is enabled for more accurate measurement.

  2. In the Measurement Parameters and History section, the T-Square tab is active. Specify the desired parameters for the measurement in the T-Square tab.

  3. Select Draw in the Controls section of the app toolstrip. To cancel drawing and start a new measurement, select Cancel.

  4. Select two points on the image in the Viewer section to set the T scale and then select a third point to measure the perpendicular distance.

  5. Right-click to complete the measurement and exit the drawing mode.

T-square measurement in the app

To measure using the angle measurement, perform these steps.

  1. From the Measure drop-down in the Controls section of the app toolstrip, select Angle. Ensure edge-snapping is enabled for more accurate measurement.

  2. In the Measurement Parameters and History section, the Angle tab is active. Specify the desired parameters for the measurement in the Angle tab.

  3. Select Draw in the Controls section of the app toolstrip. To cancel drawing and start a new measurement, select Cancel.

  4. Select a single point on the image in the Viewer section to set the vertex of the angle and then select two more points to set the sides of the angle.

  5. Right-click to complete the measurement and exit the drawing mode.

Angle measurement in the app

To measure using the circle measurement, perform these steps.

  1. From the Measure drop-down in the Controls section of the app toolstrip, select Circle. Ensure edge-snapping is enabled for more accurate measurement.

  2. In the Measurement Parameters and History section, the Circle tab is active. Specify the desired parameters for the measurement in the Circle tab.

  3. Select Draw in the Controls section of the app toolstrip. To cancel drawing and start a new measurement, select Cancel.

  4. Click and drag to draw a circle.

  5. Right-click to complete the measurement and exit the drawing mode.

Circle measurement in the app

To delete any measurements, select the check box next to those measurements in the corresponding tab of the measurement history, and then select Delete in the Controls section of the app toolstrip. To export all remaining measurements to the workspace, select Export in the Export section of the app toolstrip.

Customize the App

You can customize the code of the EdgeSnappingMeasurementApp app in the attached supporting file. You can support exporting only selected measurements by updating the relevant app methods.

To customize the app, you can choose one of these options:

  • Open the attached MLAPP files in App Designer and edit the code in the Code View.

  • Open the attached MLAPP files in App Designer, select Share in the Designer tab and then Export to MATLAB Class (.m), and save the M file. You can then edit the M file.

See Also

Apps

Properties

Functions

Topics