10

If I have a BLOB representation of a PDF file I have in my Angular Controller that I am exposing in my HTML page in the following fashion:

 //controller
 function (data) {

        var fileBack = new Blob([(data)], { type: 'application/pdf' });
        var fileURL = URL.createObjectURL(fileBack);
        $scope.content = $sce.trustAsResourceUrl(fileURL);
 }

//html
<object ng-show="content" data="{{content}}" type="application/pdf" style="width: 100%; height: 400px;"></object>

What are my options if I wanted to mask parts of the document as it is being displayed in the browser? Such cases include that I can think of (just want to prove this is possible btw):

  - Hiding the 2nd page of a document
  - Overlapping a image to hide some Width x Height space

Any ideas on how any of this could be achieved? If not from a BLOB format is it possible at all? What requirements would I have to meet to accomplish a task such as this.

Successful example in browser: https://studysoup.com/western-kentucky-university/econ-202/one-week-of-notes/econ-202-notes-week-9?id=864095

Pipeline
  • 1,029
  • 1
  • 17
  • 45
  • I imagine the only option would be to forgo the pdf displaying plugin that browsers have and resort to using `pdf.js` as the means by which it is parsed and displayed. From there, no idea of whether the library has functions which would be useful for the process, or if you'd have to modify the library for your own purposes. I expect that the fact you have it in a blob is entirely irrelevant. – enhzflep Mar 29 '16 at 23:57
  • Example of a succesfull preview: how is this achieved? https://studysoup.com/western-kentucky-university/econ-202/one-week-of-notes/econ-202-notes-week-9?id=864095 – Pipeline Mar 30 '16 at 00:08
  • Dunno. My interest and experience with PDFs is in creating them, not displaying them. Google docs apparently has an embeddable pdf viewer, amongst others. This page _might_ offer some help: http://stackoverflow.com/questions/4853898/display-pdf-within-web-browser – enhzflep Mar 30 '16 at 00:18

1 Answers1

6

You can do with this https://github.com/akrennmair/ng-pdfviewer and https://github.com/mozilla/pdf.js. Previously I made some changes to the directive and did this task. I'm not going into the deep but i made example for you. Created Plunker but somehow not able to run it https://plnkr.co/edit/xOIYGvTFJ2bU2rawg9Wc?p=preview. Here is the complete example https://drive.google.com/open?id=0Bzls0-jRP-7GMHFnQWJwUUxRYWs . Just run it on your server.

 angular.module('ngPDFViewer', []).
 directive('pdfviewer', ['$parse', function ($parse) {
        var canvas = null;
        var instance_id = null;
        var excludedPages = [];
        return {
            restrict : "E",
            template : "<div class='make-scrollable'></div>",
            scope : {
                onPageLoad : '&',
                loadProgress : '&',
                src : '@',
                id : '=',
                excludedPages : '='
            },
            controller : ['$scope', function ($scope) {
                    $scope.pageNum = 1;
                    $scope.pdfDoc = null;
                    $scope.scale = 1.0;

                    $scope.documentProgress = function (progressData) {
                        if ($scope.loadProgress) {
                            $scope.loadProgress({
                                state : "loading",
                                loaded : progressData.loaded,
                                total : progressData.total
                            });
                        }
                    };

                    $scope.loadPDF = function (path) {
                        console.log('loadPDF ', path);
                        PDFJS.getDocument(path, null, null, $scope.documentProgress).then(function (_pdfDoc) {
                            $scope.pdfDoc = _pdfDoc;
                            $scope.renderPages($scope.pageNum, function (success) {
                                if ($scope.loadProgress) {
                                    $scope.loadProgress({
                                        state : "finished",
                                        loaded : 0,
                                        total : 0
                                    });
                                }
                            });
                        }, function (message, exception) {
                            console.log("PDF load error: " + message);
                            if ($scope.loadProgress) {
                                $scope.loadProgress({
                                    state : "error",
                                    loaded : 0,
                                    total : 0
                                });
                            }
                        });
                    };

                    $scope.renderPages = function (num, callback) {
                        $scope.$apply(function () {
                            $scope.onPageLoad({
                                page : $scope.pageNum,
                                total : $scope.pdfDoc.numPages
                            });
                        });
                        for (var num = 1; num <= $scope.pdfDoc.numPages; num++){
                            var exist = $.inArray(num, excludedPages);
                            if(exist===-1){
                                $scope.pdfDoc.getPage(num).then(function(page) {
                                    $scope.renderPage(page, num)
                                })
                            }
                        }
                    };

                    $scope.renderPage = function(page, num) {
                        var viewport = page.getViewport($scope.scale);
                        var canvas = document.createElement('canvas');
                        var ctx = canvas.getContext('2d');
                        canvas.height = viewport.height;
                        canvas.width = viewport.width;
                        $('.make-scrollable').append(canvas);
                        $('.make-scrollable').height(viewport.height - 100);
                        page.render({ canvasContext: ctx, viewport: viewport }).promise.then(
                            function() { 
                                console.log("Rendered");
                            }
                       )

                    }

                    $scope.$on('pdfviewer.nextPage', function (evt, id) {
                        if (id !== instance_id) {
                            return;
                        }

                        if ($scope.pageNum < $scope.pdfDoc.numPages) {
                            $scope.pageNum++;
                            $scope.renderPage($scope.pageNum);
                        }
                    });

                    $scope.$on('pdfviewer.prevPage', function (evt, id) {
                        if (id !== instance_id) {
                            return;
                        }

                        if ($scope.pageNum > 1) {
                            $scope.pageNum--;
                            $scope.renderPage($scope.pageNum);
                        }
                    });

                    $scope.$on('pdfviewer.gotoPage', function (evt, id, page) {
                        if (id !== instance_id) {
                            return;
                        }

                        if (page >= 1 && page <= $scope.pdfDoc.numPages) {
                            $scope.pageNum = page;
                            $scope.renderPage($scope.pageNum);
                        }
                    });
                }
            ],
            link : function (scope, iElement, iAttr) {
                canvas = iElement.find('canvas')[0];
                instance_id = iAttr.id;
                excludedPages = scope.$parent.excludePages;
                iAttr.$observe('src', function (v) {
                    console.log('src attribute changed, new value is', v);
                    if (v !== undefined && v !== null && v !== '') {
                        scope.pageNum = 1;
                        scope.loadPDF(scope.src);
                    }
                });
            }
        };
    }
]).
service("PDFViewerService", ['$rootScope', function ($rootScope) {

        var svc = {};
        svc.nextPage = function () {
            $rootScope.$broadcast('pdfviewer.nextPage');
        };

        svc.prevPage = function () {
            $rootScope.$broadcast('pdfviewer.prevPage');
        };

        svc.Instance = function (id) {
            var instance_id = id;

            return {
                prevPage : function () {
                    $rootScope.$broadcast('pdfviewer.prevPage', instance_id);
                },
                nextPage : function () {
                    $rootScope.$broadcast('pdfviewer.nextPage', instance_id);
                },
                gotoPage : function (page) {
                    $rootScope.$broadcast('pdfviewer.gotoPage', instance_id, page);
                }
            };
        };

        return svc;
    }
]);
Arun Shinde
  • 1,185
  • 6
  • 12
  • I will give this a try late tomorrow or early Monday, thanks for such a lengthy response! – Pipeline Apr 03 '16 at 02:02
  • Will this work if I am exposing my PDF currently like the accepted answer in: http://stackoverflow.com/questions/21628378/angularjs-display-blob-pdf-in-an-angular-app The problem is I do not have the path of the PDF file as I am displaying the file using a BLOB of a PDF that I retrieve from a database rather than file storage. – Pipeline Apr 05 '16 at 13:18
  • Which back-end language you have? – Arun Shinde Apr 05 '16 at 15:09
  • writing my backend using WebAPI 2 in c# and OWIN – Pipeline Apr 05 '16 at 17:12