Android Open Source - pixel-art Draw Op Manager






From Project

Back to project page pixel-art.

License

The source code is released under:

Apache License

If you think the Android project pixel-art listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.jaween.pixelart.ui.undo;
//from w  w w  .j  av a2  s.co m
import android.graphics.Bitmap;

import com.jaween.pixelart.ui.animation.Frame;
import com.jaween.pixelart.util.BitmapEncoder;

import java.util.List;

/**
 * Used by first constructing the object with the initial state Bitmap. Prior to an undoable
 * drawing occurring you must pass the Bitmap in switchLayer(). After the drawing
 * call add(), this will find the differences between the new frame and the previous frame and store
 * the compressed result. The undo() function will then decompress that result and modify the input
 * to return it to what it was before the drawing operation.
 */
public class DrawOpManager {

    // Bitmaps and compression
    private Bitmap layerBeforeModification = null;
    private final BitmapEncoder bitmapEncoder = new BitmapEncoder();

    // Bitmap pixel arrays
    private int[] lhsPixelArray = null;
    private int[] rhsPixelArray = null;
    private int[] xorArray = null;

    // Layer dimensions
    private int layerWidth;
    private int layerHeight;

    public DrawOpManager(int layerWidth, int layerHeight, Bitmap.Config config) {
        // Used for storing a copy of the previous frame
        layerBeforeModification = Bitmap.createBitmap(layerWidth, layerHeight, config);

        // Holds pixel data (manipulations are faster than individual Bitmap.setPixel() calls)
        lhsPixelArray = new int[layerWidth * layerHeight];
        rhsPixelArray = new int[layerWidth * layerHeight];
        xorArray = new int[layerWidth * layerHeight];

        // Allocates memory for pixel data in the compression function
        bitmapEncoder.setBitmapDimensions(layerWidth, layerHeight);

        // Layer dimensions
        this.layerWidth = layerWidth;
        this.layerHeight = layerHeight;
    }

    /**
     * Keeps a pre-draw snapshot of the layer
     * @param currentLayer The new current layer
     */
    public void switchLayer(Bitmap currentLayer) {
        bitmapCopy(currentLayer, layerBeforeModification);
    }

    public UndoItem add(Bitmap currentLayer, int frameIndex, int layerIndex) {
        // Finds the changes between the bitmaps
        xorArray = xor(layerBeforeModification, currentLayer);

        // Compresses these differences
        Integer[] encodedChanges = bitmapEncoder.encodeRunLength(xorArray);

        // Creates an UndoItem
        DrawOpUndoData undoData = new DrawOpUndoData(encodedChanges, frameIndex, layerIndex);
        UndoItem undoItem = new UndoItem(UndoItem.Type.DRAW_OP, 0, undoData);

        // Keeps a copy of this frame for future undos/redos
        bitmapCopy(currentLayer, layerBeforeModification);

        return undoItem;
    }

    public void undo(List<Frame> frames, int currentFrameIndex, int currentLayerIndex, DrawOpUndoData undoData) {
        // The changes to be undone
        Integer[] previousChanges = undoData.getCompressedChanges();

        // Retrieves the layer which was modified
        int modifiedFrameIndex = undoData.getFrameIndex();
        int modifiedLayerIndex = undoData.getLayerIndex();
        Bitmap modifiedLayer = frames
                .get(modifiedFrameIndex)
                .getLayers()
                .get(modifiedLayerIndex)
                .getImage();

        // Rolls back the change
        performUpdate(previousChanges, modifiedLayer);

        // Keeps a copy of the currently selected layer for future undos/redos
        Bitmap currentLayer = frames
                .get(currentFrameIndex)
                .getLayers()
                .get(currentLayerIndex)
                .getImage();
        bitmapCopy(currentLayer, layerBeforeModification);
    }

    public void redo(List<Frame> frames, int currentFrameIndex, int currentLayerIndex, DrawOpUndoData redoData) {
        // Retrieves the layer which needs to be modified
        int frameToModifyIndex = redoData.getFrameIndex();
        int layerToModifyIndex = redoData.getLayerIndex();
        Bitmap layerToModify = frames
                .get(frameToModifyIndex)
                .getLayers()
                .get(layerToModifyIndex)
                .getImage();

        // Returns this change to the undo stack
        Integer[] nextChanges = redoData.getCompressedChanges();

        // Performs the redo operation to the current frame
        performUpdate(nextChanges, layerToModify);

        // Keeps a copy of the currently selected layer for future undos/redos
        Bitmap currentLayer = frames
                .get(currentFrameIndex)
                .getLayers()
                .get(currentLayerIndex)
                .getImage();
        bitmapCopy(currentLayer, layerBeforeModification);
    }

    /**
     * Updates a bitmap based on an array of compressed changes
     * This can be an undo change or a redo change
     **/
    private void performUpdate(Integer[] compressedChanges, Bitmap destination) {
        // Decodes the uncompressed changes
        bitmapEncoder.decodeRunLength(compressedChanges, xorArray);

        // Retrieves the new frame
        xor(destination, xorArray);

        // Updates the previous frame (for use with the next drawing operation)
        bitmapCopy(destination, layerBeforeModification);
    }

    /**
     * Copies the pixels from a source Bitmap into a destination Bitmap.
     **/
    private void bitmapCopy(Bitmap source, Bitmap destination) {
        source.getPixels(lhsPixelArray, 0, layerWidth, 0, 0, layerWidth, layerHeight);
        destination.setPixels(lhsPixelArray, 0, layerWidth, 0, 0, layerWidth, layerHeight);
    }

    /**
     * Finds the bitwise XOR of the two bitmaps (i.e. the differences between them).
     * @param lhs The left hand side Bitmap
     * @param rhs The right hand side Bitmap
     * @return An array containing the XOR'd pixels
     **/
    private int[] xor(Bitmap lhs, Bitmap rhs) {
        // Retrieves the pixel data of both bitmaps into the two pixel arrays
        lhs.getPixels(lhsPixelArray, 0, layerWidth, 0, 0, layerWidth, layerHeight);
        rhs.getPixels(rhsPixelArray, 0, layerWidth, 0, 0, layerWidth, layerHeight);

        // XOR's the bitmaps together
        return xor(lhsPixelArray, rhsPixelArray);
    }


    /**
     * Finds the bitwise XOR of the two parameters (i.e. the differences between them) and stores
     * the result in the lhs Bitmap.
     * @param lhs The left hand side Bitmap and destination of the result
     * @param rhs The right hand side's pixels
     **/
    private void xor(Bitmap lhs, int[] rhs) {
        // Retrieves the pixel data of the bitmap
        lhs.getPixels(lhsPixelArray, 0, layerWidth, 0, 0, layerWidth, layerHeight);

        // XOR's the parameters together
        xorArray = xor(lhsPixelArray, rhs);

        // Loads the result into the Bitmap
        lhs.setPixels(xorArray, 0, layerWidth, 0, 0, layerWidth, layerHeight);
    }

    /**
     * Performs a bitwise XOR on the elements of two arrays.
     * @param lhs The left hand side operand
     * @param rhs The right hand side operand
     * @return An array containing the XOR'd values
     */
    private int[] xor(int[] lhs, int[] rhs) {
        // Iterates over the pixels and XORs them together
        for (int y = 0; y < layerHeight; y++) {
            for (int x = 0; x < layerWidth; x++) {
                int index = x + y * layerWidth;
                xorArray[index] = lhs[index] ^ rhs[index];
            }
        }
        return xorArray;
    }
}




Java Source Code List

com.jaween.pixelart.ContainerActivity.java
com.jaween.pixelart.ContainerFragment.java
com.jaween.pixelart.PanelManagerFragment.java
com.jaween.pixelart.io.AnimationFile.java
com.jaween.pixelart.io.FileAdapter.java
com.jaween.pixelart.io.ImportExport.java
com.jaween.pixelart.io.LoadFileDialog.java
com.jaween.pixelart.tools.Command.java
com.jaween.pixelart.tools.Dropper.java
com.jaween.pixelart.tools.Eraser.java
com.jaween.pixelart.tools.FloodFill.java
com.jaween.pixelart.tools.FreeSelect.java
com.jaween.pixelart.tools.MagicWand.java
com.jaween.pixelart.tools.Oval.java
com.jaween.pixelart.tools.Pen.java
com.jaween.pixelart.tools.RectSelect.java
com.jaween.pixelart.tools.Rect.java
com.jaween.pixelart.tools.Selection.java
com.jaween.pixelart.tools.ToolReport.java
com.jaween.pixelart.tools.Tool.java
com.jaween.pixelart.tools.attributes.EraserToolAttributes.java
com.jaween.pixelart.tools.attributes.MagicWandToolAttributes.java
com.jaween.pixelart.tools.attributes.OvalToolAttributes.java
com.jaween.pixelart.tools.attributes.PenToolAttributes.java
com.jaween.pixelart.tools.attributes.RectToolAttributes.java
com.jaween.pixelart.tools.attributes.ToolAttributes.java
com.jaween.pixelart.tools.options.EraserOptionsView.java
com.jaween.pixelart.tools.options.MagicWandOptionsView.java
com.jaween.pixelart.tools.options.OvalOptionsView.java
com.jaween.pixelart.tools.options.PenOptionsView.java
com.jaween.pixelart.tools.options.RectOptionsView.java
com.jaween.pixelart.tools.options.ToolOptionsView.java
com.jaween.pixelart.ui.ColourButton.java
com.jaween.pixelart.ui.ColourSelector.java
com.jaween.pixelart.ui.DrawingFragment.java
com.jaween.pixelart.ui.DrawingSurface.java
com.jaween.pixelart.ui.PaletteFragment.java
com.jaween.pixelart.ui.PanelFragment.java
com.jaween.pixelart.ui.PixelGrid.java
com.jaween.pixelart.ui.Thumbnail.java
com.jaween.pixelart.ui.ToolButton.java
com.jaween.pixelart.ui.ToolboxFragment.java
com.jaween.pixelart.ui.TransparencyCheckerboard.java
com.jaween.pixelart.ui.animation.AnimationFragment.java
com.jaween.pixelart.ui.animation.FrameAdapter.java
com.jaween.pixelart.ui.animation.Frame.java
com.jaween.pixelart.ui.colourpicker.ColourPickerDialog.java
com.jaween.pixelart.ui.colourpicker.ColourPickerFragment.java
com.jaween.pixelart.ui.colourpicker.ColourPickerView.java
com.jaween.pixelart.ui.layer.LayerAdapter.java
com.jaween.pixelart.ui.layer.LayerFragment.java
com.jaween.pixelart.ui.layer.Layer.java
com.jaween.pixelart.ui.undo.DrawOpManager.java
com.jaween.pixelart.ui.undo.DrawOpUndoData.java
com.jaween.pixelart.ui.undo.FrameUndoData.java
com.jaween.pixelart.ui.undo.LayerUndoData.java
com.jaween.pixelart.ui.undo.UndoItem.java
com.jaween.pixelart.ui.undo.UndoManager.java
com.jaween.pixelart.util.AbsVerticalSeekBar.java
com.jaween.pixelart.util.AnimatedGifEncoder.java
com.jaween.pixelart.util.AutoSaver.java
com.jaween.pixelart.util.BitmapEncoder.java
com.jaween.pixelart.util.Color.java
com.jaween.pixelart.util.ConfigChangeFragment.java
com.jaween.pixelart.util.Debug.java
com.jaween.pixelart.util.MarchingAnts.java
com.jaween.pixelart.util.PreferenceManager.java
com.jaween.pixelart.util.ScaleListener.java
com.jaween.pixelart.util.SlideAnimator.java
com.jaween.pixelart.util.SlidingLinearLayout.java
com.jaween.pixelart.util.VerticalProgressBar.java
com.tokaracamara.android.verticalslidevar.VerticalSeekBar.java