使用 C# 进行 PDF 多媒体注释

PDF 文档中的注释包含在 Page 对象的 Annotations 集合中。该集合仅包含该单个页面的所有注释:每个页面都有自己的 Annotations 集合。要向特定页面添加注释,请使用 Add 方法将其添加到该页面的 Annotations 集合中。

使用 Aspose.PDF.InteractiveFeatures.Annotations 命名空间中的 ScreenAnnotation 类,将 SWF 文件作为注释包含在 PDF 文档中。屏幕注释指定页面上的一个区域,可以播放媒体剪辑。

当您需要在 PDF 文档中添加外部视频链接时,可以使用 MovieAnnotaiton。 Movie Annotation 包含动画图形和声音,通过计算机屏幕和扬声器呈现。

Sound Annotation 类似于文本注释,只是它包含从计算机的麦克风录制或从文件导入的声音,而不是文本注释。当激活注释时,声音将被播放。该注释在大多数方面的行为类似于文本注释,具有不同的图标(默认情况下为扬声器),以指示它表示声音。

但是,当需要将媒体嵌入 PDF 文档时,您需要使用 RichMediaAnnotation

RichMediaAnnotation 类的以下方法/属性可以使用。

  • Stream CustomPlayer { set; }: 允许设置用于播放视频的播放器。
  • string CustomFlashVariables { set; }: 允许设置传递给 Flash 应用程序的变量。此行是一组用 ‘&’ 分隔的 “key=value” 对。
  • void AddCustomData(strig name, Stream data): 为播放器添加附加数据。例如 source=video.mp4&autoPlay=true&scale=100。
  • ActivationEvent ActivateOn { get; set}: 事件激活播放器;可能的值为 Click, PageOpen, PageVisible。
  • void SetContent(Stream stream, string name): 设置要播放的视频/音频数据。
  • void Update(): 创建注释的数据结构。此方法应最后调用。
  • void SetPoster(Stream): 设置视频的海报,即播放器未激活时显示的图片。

以下代码片段也可以与 Aspose.PDF.Drawing 库一起使用。

添加屏幕注释

以下代码片段演示如何向 PDF 文件添加屏幕注释:

// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void AddScreenAnnotationWithMedia()
{
    // The path to the documents directory
    var dataDir = RunExamples.GetDataDir_AsposePdf_Annotations();

    // Open PDF document
    using (cument = new Aspose.Pdf.Document(dataDir + "sample.pdf"))
    {
        // Path to the media file (SWF)
        var mediaFile = dataDir + "input.swf";

        // Create Screen Annotation
        var screenAnnotation = new Aspose.Pdf.Annotations.ScreenAnnotation(
            document.Pages[1],
            new Aspose.Pdf.Rectangle(170, 190, 470, 380),
            mediaFile);

        // Add the annotation to the page
        document.Pages[1].Annotations.Add(screenAnnotation);

        // Save PDF document
        document.Save(dataDir + "AddScreenAnnotationWithMedia_out.pdf");
    }
}

添加声音注释

以下代码片段演示如何向 PDF 文件添加声音注释:

// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void AddSoundAnnotation()
{
    // Open PDF document
    var dataDir = RunExamples.GetDataDir_AsposePdf_Annotations();
    using (var document = new Aspose.Pdf.Document(dataDir + "sample.pdf"))
    {
        var mediaFile = dataDir + "file_example_WAV_1MG.wav";

        // Create Sound Annotation
        var soundAnnotation = new Aspose.Pdf.Annotations.SoundAnnotation(
            document.Pages[1],
            new Aspose.Pdf.Rectangle(20, 700, 60, 740),
            mediaFile)
        {
            Color = Aspose.Pdf.Color.Blue,
            Title = "John Smith",
            Subject = "Sound Annotation demo",
            Popup = new Aspose.Pdf.Annotations.PopupAnnotation(document.Pages[1], new Aspose.Pdf.Rectangle(20, 700, 60, 740))
        };

        document.Pages[1].Annotations.Add(soundAnnotation);

        // Save PDF document
        document.Save(dataDir + "AddSoundAnnotation_out.pdf");
    }
}

添加 RichMediaAnnotation

以下代码片段演示如何向 PDF 文件添加 RichMediaAnnotation:

// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void AddRichMediaAnnotation()
{
    // The path to the documents directory
    var dataDir = RunExamples.GetDataDir_AsposePdf_Annotations();

    // Create PDF document
    using (var document = new Aspose.Pdf.Document())
    {
        var pathToAdobeApp = @"C:\Program Files (x86)\Adobe\Acrobat 2017\Acrobat\Multimedia Skins";
        Page page = document.Pages.Add();

        // Define video and poster names
        const string videoName = "file_example_MP4_480_1_5MG.mp4";
        const string posterName = "file_example_MP4_480_1_5MG_poster.jpg";
        string skinName = "SkinOverAllNoFullNoCaption.swf";

        // Create RichMediaAnnotation
        var rma = new RichMediaAnnotation(page, new Aspose.Pdf.Rectangle(100, 500, 300, 600));

        // Specify the stream containing the video player code
        rma.CustomPlayer = new FileStream(Path.Combine(pathToAdobeApp, "Players", "Videoplayer.swf"), FileMode.Open, FileAccess.Read);

        // Compose flash variables line for the player
        rma.CustomFlashVariables = $"source={videoName}&skin={skinName}";

        // Add skin code
        rma.AddCustomData(skinName, new FileStream(Path.Combine(pathToAdobeApp, skinName), FileMode.Open, FileAccess.Read));

        // Set poster for the video
        rma.SetPoster(new FileStream(Path.Combine(dataDir, posterName), FileMode.Open, FileAccess.Read));

        // Set video content
        using (Stream fs = new FileStream(Path.Combine(dataDir, videoName), FileMode.Open, FileAccess.Read))
        {
            rma.SetContent(videoName, fs);
        }

        // Set type of the content (video)
        rma.Type = RichMediaAnnotation.ContentType.Video;

        // Activate player by click
        rma.ActivateOn = RichMediaAnnotation.ActivationEvent.Click;

        // Update annotation data
        rma.Update();

        // Add annotation to the page
        page.Annotations.Add(rma);

        // Save PDF document
        document.Save(dataDir + "RichMediaAnnotation_out.pdf");
    }
}

获取 MultimediaAnnotation

请尝试使用以下代码片段从 PDF 文档中获取 MultimediaAnnotation。

// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void GetMultimediaAnnotation()
{
    // The path to the documents directory
    var dataDir = RunExamples.GetDataDir_AsposePdf_Annotations();

    // Open PDF document
    using (var document = new Aspose.Pdf.Document(dataDir + "RichMediaAnnotation.pdf"))
    {
        // Get multimedia annotations (Screen, Sound, RichMedia)
        var mediaAnnotations = document.Pages[1].Annotations
            .Where(a => a.AnnotationType == Aspose.Pdf.Annotations.AnnotationType.Screen
                        || a.AnnotationType == Aspose.Pdf.Annotations.AnnotationType.Sound
                        || a.AnnotationType == Aspose.Pdf.Annotations.AnnotationType.RichMedia)
            .Cast<Aspose.Pdf.Annotations.Annotation>();

        // Iterate through the annotations and print their details
        foreach (var ma in mediaAnnotations)
        {
            Console.WriteLine($"{ma.AnnotationType} [{ma.Rect}]");
        }
    }
}

删除 MultimediaAnnotation

以下代码片段演示如何从 PDF 文件中删除 MultimediaAnnotation。

// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void DeletePolyAnnotation()
{
    // The path to the documents directory
    var dataDir = RunExamples.GetDataDir_AsposePdf_Annotations();

    // Open PDF document
    using (var document = new Aspose.Pdf.Document(dataDir + "RichMediaAnnotation.pdf"))
    {
        // Get RichMedia annotations
        var richMediaAnnotations = document.Pages[1].Annotations
            .Where(a => a.AnnotationType == Aspose.Pdf.Annotations.AnnotationType.RichMedia)
            .Cast<Aspose.Pdf.Annotations.RichMediaAnnotation>();

        // Delete each RichMedia annotation
        foreach (var rma in richMediaAnnotations)
        {
            document.Pages[1].Annotations.Delete(rma);
        }

        // Save PDF document
        document.Save(dataDir + "DeletePolyAnnotation_out.pdf");
    }
}

添加小部件注释

交互式表单使用 Widget Annotations 来表示字段的外观并管理用户交互。 我们使用这些表单元素添加到 PDF 中,以便更容易输入、提交信息或执行其他用户交互。

小部件注释是特定页面上表单字段的图形表示,因此我们不能直接将其创建为注释。

每个小部件注释将根据其类型具有适当的图形(外观)。创建后,可以更改某些视觉方面,例如边框样式和背景颜色。 其他属性,例如文本颜色和字体,可以通过字段进行更改,一旦附加到某个字段。

在某些情况下,您可能希望字段在多个页面上出现,重复相同的值。在这种情况下,通常只有一个小部件的字段可能会附加多个小部件:文本字段、列表框、组合框和复选框通常只有一个,而单选组有多个小部件,每个单选按钮一个。 填写表单的人可以使用任何这些小部件来更新字段的值,这在所有其他小部件中也会反映出来。

文档中每个位置的每个表单字段代表一个小部件注释。小部件注释的位置特定数据添加到特定页面。每个表单字段有几种变体。按钮可以是单选按钮、复选框或按钮。选择小部件可以是列表框或组合框。

在此示例中,我们将学习如何添加用于文档导航的按钮。

向文档添加按钮

// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void AddPrintButton()
{
    // The path to the documents directory
    var dataDir = RunExamples.GetDataDir_AsposePdf_Forms();

    // Create PDF document
    using (var document = new Aspose.Pdf.Document())
    {
        // Add page
        var page = document.Pages.Add();

        // Define the rectangle for the button
        var rect = new Aspose.Pdf.Rectangle(72, 748, 164, 768);

        // Create a button field
        var printButton = new Aspose.Pdf.Forms.ButtonField(page, rect)
        {
            AlternateName = "Print current document",
            Color = Aspose.Pdf.Color.Black,
            PartialName = "printBtn1",
            NormalCaption = "Print Document"
        };

        // Set the border style for the button
        var border = new Aspose.Pdf.Annotations.Border(printButton)
        {
            Style = Aspose.Pdf.Annotations.BorderStyle.Solid,
            Width = 2
        };
        printButton.Border = border;

        // Set the border and background color characteristics
        printButton.Characteristics.Border = System.Drawing.Color.FromArgb(255, 0, 0, 255);
        printButton.Characteristics.Background = System.Drawing.Color.FromArgb(255, 0, 191, 255);

        // Add the button to the form
        document.Form.Add(printButton);

        // Save PDF document
        document.Save(dataDir + "PrintButton_out.pdf");
    }
}

此按钮具有边框并设置了背景。我们还设置了按钮名称(Name)、工具提示(AlternateName)、标签(NormalCaption)和标签文本的颜色(Color)。

使用文档导航操作

存在更复杂的小部件注释用法示例 - PDF 文档中的文档导航。这可能需要准备 PDF 文档演示。

此示例演示如何创建 4 个按钮:

// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void AddNavigationButtons()
{
    // The path to the documents directory
    var dataDir = RunExamples.GetDataDir_AsposePdf_Forms();

    // Open PDF document
    using (var document = new Aspose.Pdf.Document(dataDir + "JSON Fundamenals.pdf"))
    {
        // Create an array of button fields
        var buttons = new Aspose.Pdf.Forms.ButtonField[4];

        // Define alternate names and normal captions for the buttons
        var alternateNames = new[] { "Go to first page", "Go to prev page", "Go to next page", "Go to last page" };
        var normalCaptions = new[] { "First", "Prev", "Next", "Last" };

        // Define predefined actions for the buttons
        PredefinedAction[] actions = {
            PredefinedAction.FirstPage,
            PredefinedAction.PrevPage,
            PredefinedAction.NextPage,
            PredefinedAction.LastPage
        };

        // Define border and background colors
        var clrBorder = System.Drawing.Color.FromArgb(255, 0, 255, 0);
        var clrBackGround = System.Drawing.Color.FromArgb(255, 0, 96, 70);

        // We should create the buttons without attaching them to the page.
        for (var i = 0; i < 4; i++)
        {
            buttons[i] = new Aspose.Pdf.Forms.ButtonField(document, new Aspose.Pdf.Rectangle(32 + i * 80, 28, 104 + i * 80, 68))
            {
                AlternateName = alternateNames[i],
                Color = Aspose.Pdf.Color.White,
                NormalCaption = normalCaptions[i],
                OnActivated = new Aspose.Pdf.Annotations.NamedAction(actions[i])
            };

            // Set the border style for the button
            buttons[i].Border = new Aspose.Pdf.Annotations.Border(buttons[i])
            {
                Style = Aspose.Pdf.Annotations.BorderStyle.Solid,
                Width = 2
            };

            // Set the border and background color characteristics
            buttons[i].Characteristics.Border = clrBorder;
            buttons[i].Characteristics.Background = clrBackGround;
        }

        // Duplicate the array of buttons on each page in the document
        for (var pageIndex = 1; pageIndex <= document.Pages.Count; pageIndex++)
        {
            for (var i = 0; i < 4; i++)
            {
                document.Form.Add(buttons[i], $"btn{pageIndex}_{i + 1}", pageIndex);
            }
        }

        // Save PDF document
        document.Save(dataDir + "NavigationButtons_out.pdf");

        // We call Form.Add method with the following parameters: field, name, and the index of the pages that this field will be added to.
        // And to get the full result, we need disable the “First” and “Prev” buttons on the first page and the “Next” and “Last” buttons on the last page.

        document.Form["btn1_1"].ReadOnly = true;
        document.Form["btn1_2"].ReadOnly = true;

        document.Form[$"btn{document.Pages.Count}_3"].ReadOnly = true;
        document.Form[$"btn{document.Pages.Count}_4"].ReadOnly = true;
    }
}

有关此功能的更多详细信息和可能性,请参见 处理表单

在 PDF 文档中,您可以查看和管理使用 3D CAD 或 3D 建模软件创建并嵌入 PDF 文档中的高质量 3D 内容。可以在所有方向上旋转 3D 元素,就像您手中握着它们一样。

您为什么需要 3D 图像的显示?

在过去的几年中,技术在各个领域取得了巨大的突破,这要归功于 3D 打印。3D 打印技术可以应用于教授建筑、机械工程、设计等技术技能,作为主要工具。由于个人打印设备的出现,这些技术可以促进教育过程的新形式的引入,提高动机,并形成毕业生和教师所需的能力。

3D 建模的主要任务是未来对象或物体的构思,因为要释放一个对象,您需要了解其设计特征的所有细节,以便在工业设计或建筑中进行后续再生。

添加 3D 注释

3D 注释是使用以 U3D 格式创建的模型添加的。

  1. 创建一个新的 Document

  2. 加载所需 3D 模型的数据(在我们的例子中为 “Ring.u3d”),以创建 PDF3DContent

  3. 创建 3dArtWork 对象并将其链接到文档和 3DContent。

  4. 调整 pdf3dArtWork 对象:

    • 3DLightingScheme - (我们将在示例中设置为 CAD
    • 3DRenderMode - (我们将在示例中设置为 Solid
    • 填充 ViewArray,创建至少一个 3D View 并将其添加到数组中。
  5. 在注释中设置 3 个基本参数:

    • 注释将放置的 page
    • 注释所在的 rectangle
    • 以及 3dArtWork 对象。
  6. 为了更好地展示 3D 对象,设置边框框架。

  7. 设置默认视图(例如 - 顶部)。

  8. 添加一些附加参数:名称、预览海报等。

  9. 将注释添加到 Page

  10. 保存结果。

示例

请查看以下代码片段以添加 3D 注释。

// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void Add3dAnnotation()
{
    // The path to the documents directory
    var dataDir = RunExamples.GetDataDir_AsposePdf_Annotations();

    // Create PDF document
    using (var document = new Aspose.Pdf.Document())
    {
        // Load 3D content
        var pdf3DContent = new Aspose.Pdf.Annotations.PDF3DContent(dataDir + "Ring.u3d");

        // Create 3D artwork
        var pdf3dArtWork = new Aspose.Pdf.Annotations.PDF3DArtwork(document, pdf3DContent)
        {
            LightingScheme = new Aspose.Pdf.Annotations.PDF3DLightingScheme(Aspose.Pdf.Annotations.LightingSchemeType.CAD),
            RenderMode = new Aspose.Pdf.Annotations.PDF3DRenderMode(Aspose.Pdf.Annotations.RenderModeType.Solid),
        };

        // Define matrices for different views
        var topMatrix = new Aspose.Pdf.Matrix3D(1, 0, 0, 0, -1, 0, 0, 0, -1, 0.10271, 0.08184, 0.273836);
        var frontMatrix = new Aspose.Pdf.Matrix3D(0, -1, 0, 0, 0, 1, -1, 0, 0, 0.332652, 0.08184, 0.085273);

        // Add views to the 3D artwork
        pdf3dArtWork.ViewArray.Add(new Aspose.Pdf.Annotations.PDF3DView(document, topMatrix, 0.188563, "Top")); //1
        pdf3dArtWork.ViewArray.Add(new Aspose.Pdf.Annotations.PDF3DView(document, frontMatrix, 0.188563, "Left")); //2

        // Add page
        var page = document.Pages.Add();

        // Create a 3D annotation
        var pdf3dAnnotation = new Aspose.Pdf.Annotations.PDF3DAnnotation(page, new Aspose.Pdf.Rectangle(100, 500, 300, 700), pdf3dArtWork);
        pdf3dAnnotation.Border = new Aspose.Pdf.Annotations.Border(pdf3dAnnotation);
        pdf3dAnnotation.SetDefaultViewIndex(1);
        pdf3dAnnotation.Flags = Aspose.Pdf.Annotations.AnnotationFlags.NoZoom;
        pdf3dAnnotation.Name = "Ring.u3d";

        // Set preview image if needed
        // pdf3dAnnotation.SetImagePreview(dataDir + "sample_3d.png");

        // Add the 3D annotation to the page
        document.Pages[1].Annotations.Add(pdf3dAnnotation);

        // Save PDF document
        document.Save(dataDir + "Add3dAnnotation_out.pdf");
    }
}