All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.ojil.algorithm.RgbMaskPoly Maven / Gradle / Ivy

There is a newer version: 0.0.11
Show newest version
/*
 * Copyright 2008 by Jon pA. Webb
 *     This program is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU Lesser General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR pA PARTICULAR PURPOSE.  See the
 *    GNU Lesser General Public License for more details.
 *
 *    You should have received a copy of the Lesser GNU General Public License
 *    along with this program.  If not, see .
 */

package com.github.ojil.algorithm;

import com.github.ojil.core.Error;
import com.github.ojil.core.Image;
import com.github.ojil.core.PipelineStage;
import com.github.ojil.core.Point;
import com.github.ojil.core.Quad;
import com.github.ojil.core.Rect;
import com.github.ojil.core.RgbImage;
import com.github.ojil.core.RgbMaskedImage;

/**
 * Masks a polygon in an RgbImage, setting the area inside
 * or outside the polygon to masked, depending on a parameter.
 * 
 * @author webb
 */
public class RgbMaskPoly extends PipelineStage {

    private boolean bInside;
    private Point points[];
    private BinaryHeap hx[];
    private Integer[][] rnX;
    
    /**
     * Initialize class, setting polygon to mask and
     * inside/outside choice.
     * @param points list of points to mask, in clockwise order (interior
     * on right).
     * @param bInside if true then area inside the polygon
     * is masked; if false, the area outside.
     */
    public RgbMaskPoly(Point points[], boolean bInside) {
        this.points = points;
        this.bInside = bInside;
    }
    
    /**
     * Mask a quadrilateral.
     * @param quad quadrilateral to mask
     * @param bInside if true interior of quadrilateral is masked, if false
     * exterior
     * @throws com.github.ojil.core.Error if Error thrown from getCorner.
     */
    public RgbMaskPoly(Quad quad, boolean bInside) throws Error {
        this.points = new Point[4];
        this.points[0] = quad.getCorner(0);
        this.points[1] = quad.getCorner(1);
        this.points[2] = quad.getCorner(2);
        this.points[3] = quad.getCorner(3);
        this.bInside = bInside;
    }
    
    /**
     * Mask a rectangle.
     * @param rect rectangle to mask
     * @param bInside if true, interior is masked; if false, exterior.
     */
    public RgbMaskPoly(Rect rect, boolean bInside) {
        this.points = new Point[4];
        this.points[0] = new Point(rect.getLeft(), rect.getTop());
        this.points[1] = new Point(rect.getRight(), rect.getTop());
        this.points[2] = new Point(rect.getRight(), rect.getBottom());
        this.points[3] = new Point(rect.getLeft(), rect.getBottom());
        this.bInside = bInside;
    }
    
    
    /**
     * Build a vector of intersection points of the polygon for every
     * row in the output image.
     * @param nWidth output image width
     * @param nHeight output image height
     * @throws com.github.ojil.core.Error if the BinaryHeap code does.
     */
    private void buildVector(int nWidth, int nHeight) throws Error {
        this.hx = new BinaryHeap[nHeight];
        for (int i=0; i 0) {
                if (this.bInside) {
                    this.rnX[i] = new Integer[this.hx[i].size()];
                }
                while (!this.hx[i].isEmpty()) {
                    this.rnX[i][j++] = ((BinaryHeap.ComparableInt)
                            this.hx[i].deleteMin()).intValue();
                }
            }
            if (!this.bInside) {
                this.rnX[i][j] = nWidth;
            }
        }
    }
    
    /**
     * Starting at p1 and ending at p2, add all the intersection points for
     * a scanline to the array hx.
     * @param p1 starting point
     * @param p2 ending point
     * @throws com.github.ojil.core.Error if the BinaryHeap code does
     */
    private void drawLine(Point p1, Point p2) throws Error {
        if (p1.getY()>p2.getY()) {
            Point pSwap = p1;
            p1 = p2;
            p2 = pSwap;
        }
        int yDiff = p2.getY()-p1.getY();
        for (int y = 0; y
     * This code was strongly influenced by Darel Rex Finley's code described
     * at 
     * http://alienryderflex.com/polygon_fill/.
     * @param imageInput input RgbImage
     * @throws com.github.ojil.core.Error if input is not RgbImage or the BinaryHeap
     * code used to do the sorting throws.
     */
    public void push(Image imageInput) throws Error {
        if (!(imageInput instanceof RgbImage)) {
            throw new Error(
                            Error.PACKAGE.ALGORITHM,
                            ErrorCodes.IMAGE_NOT_RGBIMAGE,
                            imageInput.toString(),
                            null,
                            null);
        }
        RgbImage rgbInput = (RgbImage) imageInput;
        RgbMaskedImage rgbOutput = new RgbMaskedImage(rgbInput);
        buildVector(rgbInput.getWidth(), rgbInput.getHeight());
        for (int i=0; i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy