મીડિયાવિકિ:Gadget-Cropimage.js

વિકિસ્રોતમાંથી

નોંધ: પાનું પ્રકાશિત કર્યા પછી, તમારે તમારા બ્રાઉઝરની કૅશ બાયપાસ કરવાની આવશ્યકતા પડી શકે છે.

  • ફાયરફોક્સ / સફારી: શીફ્ટ દબાવેલી રાખીને રિલોડ પર ક્લિક કરો, અથવા તો Ctrl-F5 કે Ctrl-R દબાવો (મેક પર ⌘-R)
  • ગુગલ ક્રોમ: Ctrl-Shift-R દબાવો (મેક પર ⌘-Shift-R)
  • ઈન્ટરનેટ એક્સપ્લોરર/એજ: Ctrl દબાવેલી રાખીને રિફ્રેશ પર ક્લિક કરો, અથવા Ctrl-F5 દબાવો
  • Opera: Ctrl-F5 દબાવો
/**
 * Tutorial script: ExtractImage ("Extract area typically image  from pdf/djvu files of pages")
 *
 * A user script which adds a link to the toolbox to show a pop-up
 * dialog with page graphic of a book  and  enable a selection of an area(typically image) in it.
 *
 * Demonstrates:
 * - Use of the API
 * - Use of jQuery
 * - Use of ResourceLoader and some of the default modules that come with it
 * - Use of localization
 *
 * (Be bold and improve it!)
 *
 * Authors:
 * Arjuna Rao Chavala, 2015, Public domain
 * 
 * Maintenace:
 * User:Jayprakash12345, 2018
 * 
 */
//$(document).ready(function() {
//$(function(mw) {
    // Import the jQuery dialog plugin before starting the rest of this script
    mw.loader.using(['jquery.ui'], function() {
    //        var cancel = function() {
    //            $("#myDialog").dialog("close");
    //        }
  
    var dialogobjcreated;
    function renderCropImageDialog(pageLinks) {
        dialogobj = $(this);
        //    	dialogobj.dialog('destroy');
        var cictext=[""];
        var scale=1.50;
       
        $dialog = $('<div></div>')
            .html(
                '<div id="container">' +
                '<canvas id="canvas1" width="300" height="400" style="border: 1px solid black;">' +
                'This text is displayed if your browser does not support HTML5 Canvas.' +
                '</canvas>' +
                '</div>'
                //				pageLinks.join( '<br /><li>' ) + '</ul>'
            )
            .dialog({
                autoOpen: true,
                title: 'Crop image!',
                dialogClass: "no-close", 
                width: '70%',
                modal: true,
                closeOnEscape: false,
//                open: function (event, ui) {
						//	 $(".ui-dialog-titlebar-close", ui.dialog || ui).hide();
//		 		},
                buttons: {
                    "Done": function() {
                        	getTemplatetext(cictext,scale);
                            console.log(cictext[0]);
        					//add to document
							var $txt = $('#wpTextbox1');
//							$txt.prepend(cictext[0]); //did not work on page namespace
							$("#wpTextbox1").val(cictext[0]+$("#wpTextbox1").val());
                        	$(this).dialog('destroy').remove();
                    },
                    "Cancel": function(event, ui) {
                        $(this).dialog('destroy').remove(); //cancel
                    }
                },
            });
    }
    function cropimage() {
            var myPageLinks = [];
            // remdering and data preparations to be done
            renderCropImageDialog(myPageLinks);
			shapeinit();
        }
        // By Simon Sarris
        // www.simonsarris.com
        // sarris@acm.org
        //
        // Code from the following pages merged by Andrew Clark (amclark7@gmail.com):
        //   http://simonsarris.com/blog/510-making-html5-canvas-useful
        //   http://simonsarris.com/blog/225-canvas-selecting-resizing-shape
        // Last update June 2013
        //
        // Free to use and distribute at will
        // So long as you are nice to people, etc

    // Constructor for Shape objects to hold data for all drawn objects.
    // For now they will just be defined as rectangles.
    function Shape(state, x, y, w, h, fill) {
        "use strict";
        // This is a very simple and unsafe constructor. All we're doing is checking if the values exist.
        // "x || 0" just means "if there is a value for x, use that. Otherwise use 0."
        // But we aren't checking anything else! We could put "Lalala" for the value of x 
        this.state = state;
        this.x = x || 0;
        this.y = y || 0;
        this.w = w || 1;
        this.h = h || 1;
        this.fill = fill || '#AAAAAA';
    }

    // Draws this shape to a given context
    Shape.prototype.draw = function(ctx, optionalColor) {
        "use strict";
        var i, cur, half;
        ctx.fillStyle = this.fill;
        ctx.fillRect(this.x, this.y, this.w, this.h);
        if (this.state.selection === this) {
            ctx.strokeStyle = this.state.selectionColor;
            ctx.lineWidth = this.state.selectionWidth;
            ctx.strokeRect(this.x, this.y, this.w, this.h);

            // draw the boxes
            half = this.state.selectionBoxSize / 2;

            // 0  1  2
            // 3     4
            // 5  6  7

            // top left, middle, right
            this.state.selectionHandles[0].x = this.x - half;
            this.state.selectionHandles[0].y = this.y - half;

            this.state.selectionHandles[1].x = this.x + this.w / 2 - half;
            this.state.selectionHandles[1].y = this.y - half;

            this.state.selectionHandles[2].x = this.x + this.w - half;
            this.state.selectionHandles[2].y = this.y - half;

            //middle left
            this.state.selectionHandles[3].x = this.x - half;
            this.state.selectionHandles[3].y = this.y + this.h / 2 - half;

            //middle right
            this.state.selectionHandles[4].x = this.x + this.w - half;
            this.state.selectionHandles[4].y = this.y + this.h / 2 - half;

            //bottom left, middle, right
            this.state.selectionHandles[6].x = this.x + this.w / 2 - half;
            this.state.selectionHandles[6].y = this.y + this.h - half;

            this.state.selectionHandles[5].x = this.x - half;
            this.state.selectionHandles[5].y = this.y + this.h - half;

            this.state.selectionHandles[7].x = this.x + this.w - half;
            this.state.selectionHandles[7].y = this.y + this.h - half;
            ctx.fillStyle = this.state.selectionBoxColor;
            for (i = 0; i < 8; i += 1) {
                cur = this.state.selectionHandles[i];
                ctx.fillRect(cur.x, cur.y, this.state.selectionBoxSize, this.state.selectionBoxSize);
            }
        }
    };

    // Determine if a point is inside the shape's bounds
    Shape.prototype.contains = function(mx, my) {
        "use strict";
        // All we have to do is make sure the Mouse X,Y fall in the area between
        // the shape's X and (X + Height) and its Y and (Y + Height)
        return (this.x <= mx) && (this.x + this.w >= mx) &&
            (this.y <= my) && (this.y + this.h >= my);
    };
	var myState=[]; //need to access it for return values for shape code
    var imageObj = new Image();
    var curResourceCounter = 0;
    var initcomplete = false;
    function CanvasState(canvas) {
        "use strict";
        // **** First some setup! ****
        this.canvas = canvas;
        this.width = canvas.width;
        this.height = canvas.height;
        this.ctx = canvas.getContext('2d');
        // This complicates things a little but but fixes mouse co-ordinate problems
        // when there's a border or padding. See getMouse for more detail
        var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop,
            html, i;
        if (document.defaultView && document.defaultView.getComputedStyle) {
            this.stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(canvas, null).paddingLeft, 10) || 0;
            this.stylePaddingTop = parseInt(document.defaultView.getComputedStyle(canvas, null).paddingTop, 10) || 0;
            this.styleBorderLeft = parseInt(document.defaultView.getComputedStyle(canvas, null).borderLeftWidth, 10) || 0;
            this.styleBorderTop = parseInt(document.defaultView.getComputedStyle(canvas, null).borderTopWidth, 10) || 0;
        }
        // Some pages have fixed-position bars (like the stumbleupon bar) at the top or left of the page
        // They will mess up mouse coordinates and this fixes that
        html = document.body.parentNode;
        this.htmlTop = html.offsetTop;
        this.htmlLeft = html.offsetLeft;
        // **** Keep track of state! ****
        this.valid = false; // when set to false, the canvas will redraw everything
        this.shapes = []; // the collection of things to be drawn
        this.dragging = false; // Keep track of when we are dragging
        this.resizeDragging = false; // Keep track of resize
        this.expectResize = -1; // save the # of the selection handle 
        // the current selected object. In the future we could turn this into an array for multiple selection
        this.selection = null;
        this.dragoffx = 0; // See mousedown and mousemove events for explanation
        this.dragoffy = 0;
        // New, holds the 8 tiny boxes that will be our selection handles
        // the selection handles will be in this order:
        // 0  1  2
        // 3     4
        // 5  6  7
        this.selectionHandles = [];
        for (i = 0; i < 8; i += 1) {
            this.selectionHandles.push(new Shape(this));
        }
    	this.displayedImageWidth = 0;
    	this.displayedImageHeight = 0;
    	this.horScalingFactor = 0;
    	this.verScalingFactor = 0;
//        this.img = imageObj;// keep imageObj outside of myState
        // **** Then events! ****
        // This is an example of a closure!
        // Right here "this" means the CanvasState. But we are making events on the Canvas itself,
        // and when the events are fired on the canvas the variable "this" is going to mean the canvas!
        // Since we still want to use this particular CanvasState in the events we have to save a reference to it.
        // This is our reference!
        myState = this;
        //fixes a problem where double clicking causes text to get selected on the canvas
        canvas.addEventListener('selectstart', function(e) {
            e.preventDefault();
            return false;
        }, false);
        // Up, down, and move are for dragging
        canvas.addEventListener('mousedown', function(e) {
            var mouse, mx, my, shapes, l, i, mySel;
            if (myState.expectResize !== -1) {
                myState.resizeDragging = true;
                return;
            }
            mouse = myState.getMouse(e);
            mx = mouse.x;
            my = mouse.y;
            shapes = myState.shapes;
            l = shapes.length;
            for (i = l - 1; i >= 0; i -= 1) {
                if (shapes[i].contains(mx, my)) {
                    mySel = shapes[i];
                    // Keep track of where in the object we clicked
                    // so we can move it smoothly (see mousemove)
                    myState.dragoffx = mx - mySel.x;
                    myState.dragoffy = my - mySel.y;
                    myState.dragging = true;
                    myState.selection = mySel;
                    myState.valid = false;
                    return;
                }
            }
            // havent returned means we have failed to select anything.
            // If there was an object selected, we deselect it
            if (myState.selection) {
                myState.selection = null;
                myState.valid = false; // Need to clear the old selection border
            }
        }, true);
        canvas.addEventListener('mousemove', function(e) {
            var mouse = myState.getMouse(e),
                mx = mouse.x,
                my = mouse.y,
                oldx, oldy, i, cur;
            if (myState.dragging) {
                mouse = myState.getMouse(e);
                // We don't want to drag the object by its top-left corner, we want to drag it
                // from where we clicked. Thats why we saved the offset and use it here
                myState.selection.x = mouse.x - myState.dragoffx;
                myState.selection.y = mouse.y - myState.dragoffy;
                myState.valid = false; // Something's dragging so we must redraw
            } else if (myState.resizeDragging) {
                // time ro resize!
                oldx = myState.selection.x;
                oldy = myState.selection.y;

                // 0  1  2
                // 3     4
                // 5  6  7
                switch (myState.expectResize) {
                    case 0:
                        myState.selection.x = mx;
                        myState.selection.y = my;
                        myState.selection.w += oldx - mx;
                        myState.selection.h += oldy - my;
                        break;
                    case 1:
                        myState.selection.y = my;
                        myState.selection.h += oldy - my;
                        break;
                    case 2:
                        myState.selection.y = my;
                        myState.selection.w = mx - oldx;
                        myState.selection.h += oldy - my;
                        break;
                    case 3:
                        myState.selection.x = mx;
                        myState.selection.w += oldx - mx;
                        break;
                    case 4:
                        myState.selection.w = mx - oldx;
                        break;
                    case 5:
                        myState.selection.x = mx;
                        myState.selection.w += oldx - mx;
                        myState.selection.h = my - oldy;
                        break;
                    case 6:
                        myState.selection.h = my - oldy;
                        break;
                    case 7:
                        myState.selection.w = mx - oldx;
                        myState.selection.h = my - oldy;
                        break;
                }

                myState.valid = false; // Something's dragging so we must redraw
            }

            // if there's a selection see if we grabbed one of the selection handles
            if (myState.selection !== null && !myState.resizeDragging) {
                for (i = 0; i < 8; i += 1) {
                    // 0  1  2
                    // 3     4
                    // 5  6  7

                    cur = myState.selectionHandles[i];

                    // we dont need to use the ghost context because
                    // selection handles will always be rectangles
                    if (mx >= cur.x && mx <= cur.x + myState.selectionBoxSize &&
                        my >= cur.y && my <= cur.y + myState.selectionBoxSize) {
                        // we found one!
                        myState.expectResize = i;
                        myState.valid = false;

                        switch (i) {
                            case 0:
                                this.style.cursor = 'nw-resize';
                                break;
                            case 1:
                                this.style.cursor = 'n-resize';
                                break;
                            case 2:
                                this.style.cursor = 'ne-resize';
                                break;
                            case 3:
                                this.style.cursor = 'w-resize';
                                break;
                            case 4:
                                this.style.cursor = 'e-resize';
                                break;
                            case 5:
                                this.style.cursor = 'sw-resize';
                                break;
                            case 6:
                                this.style.cursor = 's-resize';
                                break;
                            case 7:
                                this.style.cursor = 'se-resize';
                                break;
                        }
                        return;
                    }

                }
                // not over a selection box, return to normal
                myState.resizeDragging = false;
                myState.expectResize = -1;
                this.style.cursor = 'auto';
            }
        }, true);
        canvas.addEventListener('mouseup', function(e) {
            myState.dragging = false;
            myState.resizeDragging = false;
            myState.expectResize = -1;
            if (myState.selection !== null) {
                if (myState.selection.w < 0) {
                    myState.selection.w = -myState.selection.w;
                    myState.selection.x -= myState.selection.w;
                }
                if (myState.selection.h < 0) {
                    myState.selection.h = -myState.selection.h;
                    myState.selection.y -= myState.selection.h;
                }
            }
        }, true);
        // double click for making new shapes .. not needed
        //canvas.addEventListener('dblclick', function(e) {
        //  var mouse = myState.getMouse(e);
        //  myState.addShape(new Shape(myState, mouse.x - 10, mouse.y - 10, 20, 20, 'rgba(0,255,0,.6)'));
        //}, true);
        // **** Options! ****
        this.selectionColor = '#CC0000';
        this.selectionWidth = 2;
        this.selectionBoxSize = 6;
        this.selectionBoxColor = 'darkred';
        this.interval = 30;
        //  this.bSize=0; //to store displayed image width
        setInterval(function() {
            myState.draw();
        }, myState.interval);
    }

    CanvasState.prototype.addShape = function(shape) {
        "use strict";
        this.shapes.push(shape);
        this.valid = false;
    };

    CanvasState.prototype.clear = function() {
        "use strict";
        this.ctx.clearRect(0, 0, this.width, this.height);
    };

    // While draw is called as often as the INTERVAL variable demands,
    // It only ever does something if the canvas gets invalidated by our code
    CanvasState.prototype.draw = function() {
        "use strict";
        var ctx, shapes, l, i, shape, mySel, img;
        // if our state is invalid, redraw and validate!
        if (!this.valid) {
            ctx = this.ctx;
            shapes = this.shapes;
            img = imageObj;
            this.clear();
            //log shape location
            //    console.log("Scaled image width, height:",displayedImageWidth,displayedImageHeight);
            //    console.log("Ext Image location:", shapes[0].x,shapes[0].y);
            //    console.log("Ext extents:",shapes[0].w,shapes[0].h);
            //output Template text
            // ** Add stuff you want drawn in the background all the time here **
            //*** Background picture on which graphic part is to be selected**
	//add background image
           if (curResourceCounter > 0) {
                // if height is more than width make height is equal to canvas height
                if (img.height >= img.width) {
                    this.displayedImageHeight = this.height;
                    this.verScalingFactor = this.height / img.height;
                    this.displayedImageWidth = Math.round(this.verScalingFactor * img.width);
                    this.horScalingFactor = this.verScalingFactor;
                } else {
                    this.displayedImageWidth = this.width;
                    this.horScalingFactor = this.width / img.width;
                    this.displayedImageHeight = Math.round(this.horScalingFactor * img.height);
                    this.verScalingFactor = this.horScalingFactor;
                }
                // if width is more than height  make width equal to canvas height
                //   this.bSize=displayedImageWidth;
//                imgSmall.removeAttr("class").removeAttr("height").removeAttr("style").css("width", "inherit");
// append to DOM for drawing
//				$("canvas1").append(imgSmall);
                ctx.drawImage(img, 0, 0, this.displayedImageWidth, this.displayedImageHeight);
                //first time setting of shape for center of image
                if (initcomplete  ){
                    shapes[0].x = Math.round(this.displayedImageWidth / 2 - 0.1 * this.displayedImageWidth);
                    shapes[0].y = Math.round(this.displayedImageHeight / 2 - 0.1 * this.displayedImageHeight);
                    shapes[0].w = Math.round(0.2 * this.displayedImageWidth);
                    shapes[0].h = Math.round(0.2 * this.displayedImageHeight);
                    initcomplete = false; 
                }
            }
            // draw all shapes
            l = shapes.length;
            for (i = 0; i < l; i += 1) {
                shape = shapes[i];
                // We can skip the drawing of elements that have moved off the screen:
                if (shape.x <= this.width && shape.y <= this.height &&
                    shape.x + shape.w >= 0 && shape.y + shape.h >= 0) {
                    shapes[i].draw(ctx);
                }
            }
            // draw selection
            // right now this is just a stroke along the edge of the selected Shape
            if (this.selection !== null) {
                ctx.strokeStyle = this.selectionColor;
                ctx.lineWidth = this.selectionWidth;
                mySel = this.selection;
                ctx.strokeRect(mySel.x, mySel.y, mySel.w, mySel.h);
            }
            // ** Add stuff you want drawn on top all the time here **
            this.valid = true;
        }
    };
    // Creates an object with x and y defined, set to the mouse position relative to the state's canvas
    // If you wanna be super-correct this can be tricky, we have to worry about padding and borders
    CanvasState.prototype.getMouse = function(e) {
        "use strict";
        var element = this.canvas,
            offsetX = 0,
            offsetY = 0,
            mx, my;

        // Compute the total offset
        if (element.offsetParent !== undefined) {
            do {
                offsetX += element.offsetLeft;
                offsetY += element.offsetTop;
                element = element.offsetParent;
            } while (element);
        }

        // Add padding and border style widths to offset
        // Also add the <html> offsets in case there's a position:fixed bar
        offsetX += this.stylePaddingLeft + this.styleBorderLeft + this.htmlLeft;
        offsetY += this.stylePaddingTop + this.styleBorderTop + this.htmlTop;

        mx = e.pageX - offsetX;
        my = e.pageY - offsetY;

        // We return a simple javascript object (a hash) with x and y defined
        return {
            x: mx,
            y: my
        };
    };
    var getTemplatetext = function(a,scale) {
    	    //{{Css image crop

    var cic = {
        Image: "",
        Page: 0,
        bSize: 0,
        cWidth: 0,
        cHeight: 0,
        oTop: 0,
        oLeft: 0,
        Location: "",
        Description: ""
    };
	var str="";
    //|Image   =TeluguVariJanapadaKalarupalu.djvu
    //|Page    = 35
    //|bSize   = 351
    //|cWidth  = 274
    //|cHeight = 165
    //|oTop    =210
    //|oLeft   = 17
    //|Location = center
    //|Description    = 
    //}}
    	var cictext=a[0];
        //   console.log('{{Css image crop');
        str = imageObj.src;
        if (str===null){
        	alert('Wait for scan image of page to load completely and then try');
        }
        cic.Image = str.substring(str.search("px-") + 3, str.search(".jpg"));
        str = str.match(/page[0-9]+/);
        cic.Page = str[0].replace("page", "");
        cic.bSize = Math.round(myState.displayedImageWidth*scale);
        cic.cWidth = Math.round(myState.shapes[0].w*scale);
        cic.cHeight = Math.round(myState.shapes[0].h*scale);
        cic.oTop = Math.round(myState.shapes[0].y*scale);
        cic.oLeft = Math.round(myState.shapes[0].x*scale);
        cic.Location = "center";
        cic.Description = "";
        //compose string
        //{"Image":"file:///home/arjun/extractimagejq/images/page35-3091px-TeluguVariJanapadaKalarupalu.djvu.jpg","Page":1,"bSize":281,"cWidth":56,"cHeight":80,"oTop":160,"oLeft":112,"Location":"","Description":""}
		cictext = "{{Css image crop\n";
        cictext += "|Image = " + decodeURIComponent(cic.Image) + "\n";
        cictext += "|Page = " + cic.Page + "\n";
        cictext += "|bSize = " + cic.bSize + "\n";
        cictext += "|cWidth = " + cic.cWidth + "\n";
        cictext += "|cHeight = " + cic.cHeight + "\n";
        cictext += "|oTop = " + cic.oTop + "\n";
        cictext += "|oLeft = " + cic.oLeft + "\n";
        cictext += "|Location = " + cic.Location + "\n";
        cictext += "|Description = " + cic.Description + "\n}}\n";
        a[0]=cictext;
        return true;
    };

    // If you dont want to use <body onLoad='init()'>
    // You could uncomment this init() reference and place the script reference inside the body tag
    //init();

    function shapeinit() {
        "use strict";

        var s = new CanvasState(document.getElementById('canvas1'));

        // add a large green rectangle dummy will be set after img size is available
        s.addShape(new Shape(s, 0, 0, 50, 50, 'rgba(0,205,0,0.7)'));
        var imgSmall = $('.prp-page-image img');
          imageObj.height = imgSmall.attr('height');
          imageObj.width = imgSmall.attr('width');
      imageObj.onload = function () {
        ++curResourceCounter;
        initcomplete = true;
        myState.valid = false;
//        alert("img loaded "+imageObj.src);
      };
      imageObj.src = imgSmall.attr('src');
//      alert("img src "+imageObj.src);
        // add a green-blue rectangle
        //  s.addShape(new Shape(s, 240, 120, 40, 40, 'rgba(2,165,165,0.7)'));
        // add a smaller purple rectangle
        //  s.addShape(new Shape(s, 5, 60, 25, 25, 'rgba(150,150,250,0.7)'));
    }
    
    var customizeToolbar = function() {
    	if (mw.config.get("wgCanonicalNamespace")=="Page") {
//		if ( typeof $ != 'undefined' && typeof $.fn.wikiEditor != 'undefined' ) {$( function() {
        $('#wpTextbox1').wikiEditor('addToToolbar', {
            section: 'main',
            group: 'insert',
            tools: {
                "strikethrough": {
                    label: 'Crop image',
                    type: 'button',
//                    filters: ['body.ns-250, body.ns-page'],
                    icon: '//upload.wikimedia.org/wikipedia/commons/thumb/e/e4/Crop_button.svg/23px-Crop_button.svg.png',
                    action: {
                        type: 'callback',
                        execute: function(context) {
                            cropimage();
                        }
                    }
                }
            }
     	});
		}
    };
    /* Check if view is in edit mode and that the required modules are available. Then, customize the toolbar … */
    if ( $.inArray( mw.config.get( 'wgAction' ), [ 'edit', 'submit' ] ) !== -1 ) {
        $.when( mw.loader.using( 'ext.wikiEditor' ), $.ready)
         .then( customizeToolbar );
	}
});
//});
//})(mediawiki);