Add getPixels/setPixels

This commit is contained in:
Joshua Granick
2014-08-03 18:44:28 -07:00
parent a3f8c34231
commit b8dfe9235b
3 changed files with 159 additions and 0 deletions

View File

@@ -14,6 +14,7 @@ import lime.utils.UInt8Array;
import lime.system.System; import lime.system.System;
#if js #if js
import js.html.CanvasElement;
import js.html.ImageElement; import js.html.ImageElement;
import js.Browser; import js.Browser;
#elseif flash #elseif flash
@@ -320,6 +321,15 @@ class Image {
} }
public static function fromCanvas (canvas:#if js CanvasElement #else Dynamic #end):Image {
var buffer = new ImageBuffer (null, canvas.width, canvas.height);
buffer.src = canvas;
return new Image (buffer);
}
public static function fromFile (path:String, onload:Image -> Void = null, onerror:Void -> Void = null):Image { public static function fromFile (path:String, onload:Image -> Void = null, onerror:Void -> Void = null):Image {
var image = new Image (); var image = new Image ();
@@ -400,6 +410,38 @@ class Image {
} }
public function getPixels (rect:Rectangle):ByteArray {
if (buffer == null) return null;
switch (type) {
case CANVAS:
return ImageCanvasUtil.getPixels (this, rect);
case DATA:
#if js
ImageCanvasUtil.convertToData (this);
#end
return ImageDataUtil.getPixels (this, rect);
case FLASH:
rect.offset (offsetX, offsetY);
return buffer.__srcBitmapData.getPixels (rect.__toFlashRectangle ());
default:
return null;
}
}
public function setPixel (x:Int, y:Int, color:Int):Void { public function setPixel (x:Int, y:Int, color:Int):Void {
if (buffer == null || x < 0 || y < 0 || x >= width || y >= height) return; if (buffer == null || x < 0 || y < 0 || x >= width || y >= height) return;
@@ -458,6 +500,37 @@ class Image {
} }
public function setPixels (rect:Rectangle, byteArray:ByteArray):Void {
rect = __clipRect (rect);
if (buffer == null || rect == null) return;
switch (type) {
case CANVAS:
ImageCanvasUtil.setPixels (this, rect, byteArray);
case DATA:
#if js
ImageCanvasUtil.convertToData (this);
#end
ImageDataUtil.setPixels (this, rect, byteArray);
case FLASH:
rect.offset (offsetX, offsetY);
buffer.__srcBitmapData.setPixels (rect.__toFlashRectangle (), byteArray);
default:
}
}
private static function __base64Encode (bytes:ByteArray):String { private static function __base64Encode (bytes:ByteArray):String {
#if js #if js

View File

@@ -6,6 +6,7 @@ import lime.graphics.ImageBuffer;
import lime.math.ColorMatrix; import lime.math.ColorMatrix;
import lime.math.Rectangle; import lime.math.Rectangle;
import lime.math.Vector2; import lime.math.Vector2;
import lime.utils.ByteArray;
import lime.utils.UInt8Array; import lime.utils.UInt8Array;
#if js #if js
@@ -216,6 +217,16 @@ class ImageCanvasUtil {
} }
public static function getPixels (image:Image, rect:Rectangle):ByteArray {
convertToCanvas (image);
createImageData (image);
return ImageDataUtil.getPixels (image, rect);
}
public static function setPixel (image:Image, x:Int, y:Int, color:Int):Void { public static function setPixel (image:Image, x:Int, y:Int, color:Int):Void {
convertToCanvas (image); convertToCanvas (image);
@@ -236,6 +247,16 @@ class ImageCanvasUtil {
} }
public static function setPixels (image:Image, rect:Rectangle, byteArray:ByteArray):Void {
convertToCanvas (image);
createImageData (image);
ImageDataUtil.setPixels (image, rect, byteArray);
}
public static function sync (image:Image):Void { public static function sync (image:Image):Void {
#if js #if js

View File

@@ -6,6 +6,7 @@ import lime.graphics.Image;
import lime.math.ColorMatrix; import lime.math.ColorMatrix;
import lime.math.Rectangle; import lime.math.Rectangle;
import lime.math.Vector2; import lime.math.Vector2;
import lime.utils.ByteArray;
import lime.utils.UInt8Array; import lime.utils.UInt8Array;
@@ -321,6 +322,41 @@ class ImageDataUtil {
} }
public static function getPixels (image:Image, rect:Rectangle):ByteArray {
var byteArray = new ByteArray ();
// TODO: optimize if the rect is the same as the full buffer size
var srcData = image.buffer.data;
var srcStride = Std.int (image.buffer.width * 4);
var srcPosition = Std.int ((rect.x * 4) + (srcStride * rect.y));
var srcRowOffset = srcStride - Std.int (4 * rect.width);
var srcRowEnd = Std.int (4 * (rect.x + rect.width));
var length = Std.int (4 * rect.width * rect.height);
#if js
byteArray.length = length;
#end
for (i in 0...length) {
byteArray.__set (i, srcData[srcPosition++]);
if ((srcPosition % srcStride) > srcRowEnd) {
srcPosition += srcRowOffset;
}
}
byteArray.position = 0;
return byteArray;
}
public static function multiplyAlpha (image:Image):Void { public static function multiplyAlpha (image:Image):Void {
var data = image.buffer.data; var data = image.buffer.data;
@@ -415,6 +451,35 @@ class ImageDataUtil {
} }
public static function setPixels (image:Image, rect:Rectangle, byteArray:ByteArray):Void {
var len = Math.round (4 * rect.width * rect.height);
// TODO: optimize when rect is the same as the buffer size
var data = image.buffer.data;
var offset = Math.round (4 * buffer.width * (rect.y + image.offsetX) + (rect.x + image.offsetY) * 4);
var pos = offset;
var boundR = Math.round (4 * (rect.x + rect.width + image.offsetX));
for (i in 0...len) {
if (((pos) % (width * 4)) > boundR - 1) {
pos += width * 4 - boundR;
}
data[pos] = byteArray.readByte ();
pos++;
}
image.dirty = true;
}
public static function unmultiplyAlpha (image:Image):Void { public static function unmultiplyAlpha (image:Image):Void {
if (__clamp == null) { if (__clamp == null) {