Add getPixels/setPixels
This commit is contained in:
@@ -14,6 +14,7 @@ import lime.utils.UInt8Array;
|
||||
import lime.system.System;
|
||||
|
||||
#if js
|
||||
import js.html.CanvasElement;
|
||||
import js.html.ImageElement;
|
||||
import js.Browser;
|
||||
#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 {
|
||||
|
||||
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 {
|
||||
|
||||
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 {
|
||||
|
||||
#if js
|
||||
|
||||
@@ -6,6 +6,7 @@ import lime.graphics.ImageBuffer;
|
||||
import lime.math.ColorMatrix;
|
||||
import lime.math.Rectangle;
|
||||
import lime.math.Vector2;
|
||||
import lime.utils.ByteArray;
|
||||
import lime.utils.UInt8Array;
|
||||
|
||||
#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 {
|
||||
|
||||
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 {
|
||||
|
||||
#if js
|
||||
|
||||
@@ -6,6 +6,7 @@ import lime.graphics.Image;
|
||||
import lime.math.ColorMatrix;
|
||||
import lime.math.Rectangle;
|
||||
import lime.math.Vector2;
|
||||
import lime.utils.ByteArray;
|
||||
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 {
|
||||
|
||||
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 {
|
||||
|
||||
if (__clamp == null) {
|
||||
|
||||
Reference in New Issue
Block a user