* ImageRaster now supports Android. However the constructor can no longer be used. Instead user should create it by using ImageRaster.create() which automatically defers the handling to JmeSystem.
* TestImageRaster tests both reading and writing from various types of formats now by chaining the image conversions * git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9710 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
5aca23f9b3
commit
2a11aae3a4
@ -3,8 +3,10 @@ package com.jme3.asset;
|
|||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.graphics.Matrix;
|
import android.graphics.Matrix;
|
||||||
|
import com.jme3.math.ColorRGBA;
|
||||||
import com.jme3.texture.Image;
|
import com.jme3.texture.Image;
|
||||||
import com.jme3.texture.Image.Format;
|
import com.jme3.texture.Image.Format;
|
||||||
|
import com.jme3.texture.image.ImageRaster;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@ -18,7 +20,7 @@ import java.util.logging.Logger;
|
|||||||
*
|
*
|
||||||
* @author Kirill Vainer
|
* @author Kirill Vainer
|
||||||
*/
|
*/
|
||||||
public class AndroidImageInfo {
|
public class AndroidImageInfo extends ImageRaster {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(AndroidImageInfo.class.getName());
|
private static final Logger logger = Logger.getLogger(AndroidImageInfo.class.getName());
|
||||||
|
|
||||||
@ -57,6 +59,20 @@ public class AndroidImageInfo {
|
|||||||
return format;
|
return format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPixel(int x, int y, ColorRGBA color) {
|
||||||
|
getBitmap().setPixel(x, y, color.asIntARGB());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ColorRGBA getPixel(int x, int y, ColorRGBA store) {
|
||||||
|
if (store == null) {
|
||||||
|
store = new ColorRGBA();
|
||||||
|
}
|
||||||
|
store.fromIntARGB(getBitmap().getPixel(x, y));
|
||||||
|
return store;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the bitmap directly from the asset info, possibly updating
|
* Loads the bitmap directly from the asset info, possibly updating
|
||||||
* or creating the image object.
|
* or creating the image object.
|
||||||
|
@ -5,11 +5,15 @@ import android.app.AlertDialog;
|
|||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import com.jme3.asset.AndroidAssetManager;
|
import com.jme3.asset.AndroidAssetManager;
|
||||||
|
import com.jme3.asset.AndroidImageInfo;
|
||||||
import com.jme3.asset.AssetManager;
|
import com.jme3.asset.AssetManager;
|
||||||
import com.jme3.audio.AudioRenderer;
|
import com.jme3.audio.AudioRenderer;
|
||||||
import com.jme3.audio.android.AndroidAudioRenderer;
|
import com.jme3.audio.android.AndroidAudioRenderer;
|
||||||
import com.jme3.system.*;
|
import com.jme3.system.*;
|
||||||
import com.jme3.system.JmeContext.Type;
|
import com.jme3.system.JmeContext.Type;
|
||||||
|
import com.jme3.texture.Image;
|
||||||
|
import com.jme3.texture.image.DefaultImageRaster;
|
||||||
|
import com.jme3.texture.image.ImageRaster;
|
||||||
import com.jme3.util.AndroidScreenshots;
|
import com.jme3.util.AndroidScreenshots;
|
||||||
import com.jme3.util.JmeFormatter;
|
import com.jme3.util.JmeFormatter;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -25,6 +29,13 @@ public class JmeAndroidSystem extends JmeSystemDelegate {
|
|||||||
|
|
||||||
private static Activity activity;
|
private static Activity activity;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
System.loadLibrary("bulletjme");
|
||||||
|
} catch (UnsatisfiedLinkError e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeImageFile(OutputStream outStream, String format, ByteBuffer imageData, int width, int height) throws IOException {
|
public void writeImageFile(OutputStream outStream, String format, ByteBuffer imageData, int width, int height) throws IOException {
|
||||||
Bitmap bitmapImage = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
Bitmap bitmapImage = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||||
@ -41,10 +52,12 @@ public class JmeAndroidSystem extends JmeSystemDelegate {
|
|||||||
bitmapImage.recycle();
|
bitmapImage.recycle();
|
||||||
}
|
}
|
||||||
|
|
||||||
static {
|
@Override
|
||||||
try {
|
public ImageRaster createImageRaster(Image image, int slice) {
|
||||||
System.loadLibrary("bulletjme");
|
if (image.getEfficentData() != null) {
|
||||||
} catch (UnsatisfiedLinkError e) {
|
return (AndroidImageInfo) image.getEfficentData();
|
||||||
|
} else {
|
||||||
|
return new DefaultImageRaster(image, slice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,8 @@ package com.jme3.system;
|
|||||||
import com.jme3.asset.AssetManager;
|
import com.jme3.asset.AssetManager;
|
||||||
import com.jme3.audio.AudioRenderer;
|
import com.jme3.audio.AudioRenderer;
|
||||||
import com.jme3.input.SoftTextDialogInput;
|
import com.jme3.input.SoftTextDialogInput;
|
||||||
|
import com.jme3.texture.Image;
|
||||||
|
import com.jme3.texture.image.ImageRaster;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@ -131,6 +133,11 @@ public class JmeSystem {
|
|||||||
return systemDelegate.newAudioRenderer(settings);
|
return systemDelegate.newAudioRenderer(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ImageRaster createImageRaster(Image image, int slice) {
|
||||||
|
checkDelegate();
|
||||||
|
return systemDelegate.createImageRaster(image, slice);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays an error message to the user in whichever way the context
|
* Displays an error message to the user in whichever way the context
|
||||||
* feels is appropriate. If this is a headless or an offscreen surface
|
* feels is appropriate. If this is a headless or an offscreen surface
|
||||||
|
@ -34,6 +34,8 @@ package com.jme3.system;
|
|||||||
import com.jme3.asset.AssetManager;
|
import com.jme3.asset.AssetManager;
|
||||||
import com.jme3.audio.AudioRenderer;
|
import com.jme3.audio.AudioRenderer;
|
||||||
import com.jme3.input.SoftTextDialogInput;
|
import com.jme3.input.SoftTextDialogInput;
|
||||||
|
import com.jme3.texture.Image;
|
||||||
|
import com.jme3.texture.image.ImageRaster;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@ -153,4 +155,6 @@ public abstract class JmeSystemDelegate {
|
|||||||
public abstract AudioRenderer newAudioRenderer(AppSettings settings);
|
public abstract AudioRenderer newAudioRenderer(AppSettings settings);
|
||||||
|
|
||||||
public abstract void initialize(AppSettings settings);
|
public abstract void initialize(AppSettings settings);
|
||||||
|
|
||||||
|
public abstract ImageRaster createImageRaster(Image image, int slice);
|
||||||
}
|
}
|
||||||
|
@ -26,27 +26,41 @@ class BitMaskImageCodec extends ImageCodec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static int readPixelRaw(ByteBuffer buf, int idx, int bpp) {
|
private static int readPixelRaw(ByteBuffer buf, int idx, int bpp) {
|
||||||
idx += bpp;
|
//idx += bpp;
|
||||||
int original = buf.get(--idx) & 0xff;
|
//int original = buf.get(--idx) & 0xff;
|
||||||
while ((--bpp) > 0) {
|
//while ((--bpp) > 0) {
|
||||||
original = (original << 8) | (buf.get(--idx) & 0xff);
|
// original = (original << 8) | (buf.get(--idx) & 0xff);
|
||||||
|
//}
|
||||||
|
//return original;
|
||||||
|
//return buf.getInt(idx) & (0xFFFFFFFF >>> (32 - bpp));
|
||||||
|
int pixel = 0;
|
||||||
|
buf.position(idx);
|
||||||
|
for (int i = 0; i < bpp; i++) {
|
||||||
|
pixel = pixel | (buf.get() & 0xff) << (i * 8);
|
||||||
}
|
}
|
||||||
return original;
|
return pixel;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writePixelRaw(ByteBuffer buf, int idx, int pixel, int bpp){
|
private void writePixelRaw(ByteBuffer buf, int idx, int pixel, int bpp){
|
||||||
// buf.position(idx);
|
// buf.position(idx);
|
||||||
// if (!be){
|
// if (!be){
|
||||||
while ((--bpp) >= 0){
|
// This works:
|
||||||
byte bt = (byte) ((pixel >> (bpp * 8)) & 0xff);
|
// while ((--bpp) >= 0){
|
||||||
buf.put(idx + bpp, bt);
|
// byte bt = (byte) ((pixel >> (bpp * 8)) & 0xff);
|
||||||
}
|
// buf.put(idx + bpp, bt);
|
||||||
|
// }
|
||||||
|
// ==
|
||||||
// } else {
|
// } else {
|
||||||
// for (int i = bpp - 1; i >= 0; i--) {
|
// for (int i = bpp - 1; i >= 0; i--) {
|
||||||
// byte bt = (byte) ((pixel >> (i * 8)) & 0xff);
|
// byte bt = (byte) ((pixel >> (i * 8)) & 0xff);
|
||||||
// buf.put(idx + i, bt);
|
// buf.put(idx + i, bt);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
buf.position(idx);
|
||||||
|
for (int i = 0; i < bpp; i++) {
|
||||||
|
buf.put( (byte)((pixel >> (8 * i)) & 0xff) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
114
engine/src/core/com/jme3/texture/image/DefaultImageRaster.java
Normal file
114
engine/src/core/com/jme3/texture/image/DefaultImageRaster.java
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
package com.jme3.texture.image;
|
||||||
|
|
||||||
|
import com.jme3.math.ColorRGBA;
|
||||||
|
import com.jme3.math.FastMath;
|
||||||
|
import com.jme3.texture.Image;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
public class DefaultImageRaster extends ImageRaster {
|
||||||
|
|
||||||
|
private final int[] components = new int[4];
|
||||||
|
private final ByteBuffer buffer;
|
||||||
|
private final Image image;
|
||||||
|
private final ImageCodec codec;
|
||||||
|
private final int width;
|
||||||
|
private final int height;
|
||||||
|
private final byte[] temp;
|
||||||
|
|
||||||
|
private void rangeCheck(int x, int y) {
|
||||||
|
if (x < 0 || y < 0 || x >= width || y >= height) {
|
||||||
|
throw new IllegalArgumentException("x and y must be inside the image dimensions");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DefaultImageRaster(Image image, int slice) {
|
||||||
|
this.image = image;
|
||||||
|
this.buffer = image.getData(slice);
|
||||||
|
this.codec = ImageCodec.lookup(image.getFormat());
|
||||||
|
this.width = image.getWidth();
|
||||||
|
this.height = image.getHeight();
|
||||||
|
if (codec instanceof ByteAlignedImageCodec) {
|
||||||
|
this.temp = new byte[codec.bpp];
|
||||||
|
} else {
|
||||||
|
this.temp = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPixel(int x, int y, ColorRGBA color) {
|
||||||
|
rangeCheck(x, y);
|
||||||
|
|
||||||
|
// Check flags for grayscale
|
||||||
|
if ((codec.flags & ImageCodec.FLAG_GRAY) != 0) {
|
||||||
|
float gray = color.r * 0.27f + color.g * 0.67f + color.b * 0.06f;
|
||||||
|
color = new ColorRGBA(gray, gray, gray, color.a);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((codec.flags & ImageCodec.FLAG_F16) != 0) {
|
||||||
|
components[0] = (int) FastMath.convertFloatToHalf(color.a);
|
||||||
|
components[1] = (int) FastMath.convertFloatToHalf(color.r);
|
||||||
|
components[2] = (int) FastMath.convertFloatToHalf(color.g);
|
||||||
|
components[3] = (int) FastMath.convertFloatToHalf(color.b);
|
||||||
|
} else if ((codec.flags & ImageCodec.FLAG_F32) != 0) {
|
||||||
|
components[0] = (int) Float.floatToIntBits(color.a);
|
||||||
|
components[1] = (int) Float.floatToIntBits(color.r);
|
||||||
|
components[2] = (int) Float.floatToIntBits(color.g);
|
||||||
|
components[3] = (int) Float.floatToIntBits(color.b);
|
||||||
|
} else {
|
||||||
|
// Convert color to bits by multiplying by size
|
||||||
|
components[0] = Math.min( (int) (color.a * codec.maxAlpha + 0.5f), codec.maxAlpha);
|
||||||
|
components[1] = Math.min( (int) (color.r * codec.maxRed + 0.5f), codec.maxRed);
|
||||||
|
components[2] = Math.min( (int) (color.g * codec.maxGreen + 0.5f), codec.maxGreen);
|
||||||
|
components[3] = Math.min( (int) (color.b * codec.maxBlue + 0.5f), codec.maxBlue);
|
||||||
|
}
|
||||||
|
|
||||||
|
codec.writeComponents(buffer, x, y, width, components, temp);
|
||||||
|
|
||||||
|
image.setUpdateNeeded();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ColorRGBA getPixel(int x, int y, ColorRGBA store) {
|
||||||
|
rangeCheck(x, y);
|
||||||
|
|
||||||
|
codec.readComponents(buffer, x, y, width, components, temp);
|
||||||
|
|
||||||
|
if (store == null) {
|
||||||
|
store = new ColorRGBA();
|
||||||
|
}
|
||||||
|
if ((codec.flags & ImageCodec.FLAG_F16) != 0) {
|
||||||
|
store.set(FastMath.convertHalfToFloat((short)components[1]),
|
||||||
|
FastMath.convertHalfToFloat((short)components[2]),
|
||||||
|
FastMath.convertHalfToFloat((short)components[3]),
|
||||||
|
FastMath.convertHalfToFloat((short)components[0]));
|
||||||
|
} else if ((codec.flags & ImageCodec.FLAG_F32) != 0) {
|
||||||
|
store.set(Float.intBitsToFloat((int)components[1]),
|
||||||
|
Float.intBitsToFloat((int)components[2]),
|
||||||
|
Float.intBitsToFloat((int)components[3]),
|
||||||
|
Float.intBitsToFloat((int)components[0]));
|
||||||
|
} else {
|
||||||
|
// Convert to float and divide by bitsize to get into range 0.0 - 1.0.
|
||||||
|
store.set((float)components[1] / codec.maxRed,
|
||||||
|
(float)components[2] / codec.maxGreen,
|
||||||
|
(float)components[3] / codec.maxBlue,
|
||||||
|
(float)components[0] / codec.maxAlpha);
|
||||||
|
}
|
||||||
|
if ((codec.flags & ImageCodec.FLAG_GRAY) != 0) {
|
||||||
|
store.g = store.b = store.r;
|
||||||
|
} else {
|
||||||
|
if (codec.maxRed == 0) {
|
||||||
|
store.r = 1;
|
||||||
|
}
|
||||||
|
if (codec.maxGreen == 0) {
|
||||||
|
store.g = 1;
|
||||||
|
}
|
||||||
|
if (codec.maxBlue == 0) {
|
||||||
|
store.b = 1;
|
||||||
|
}
|
||||||
|
if (codec.maxAlpha == 0) {
|
||||||
|
store.a = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return store;
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@ package com.jme3.texture.image;
|
|||||||
|
|
||||||
import com.jme3.math.ColorRGBA;
|
import com.jme3.math.ColorRGBA;
|
||||||
import com.jme3.math.FastMath;
|
import com.jme3.math.FastMath;
|
||||||
|
import com.jme3.system.JmeSystem;
|
||||||
import com.jme3.texture.Image;
|
import com.jme3.texture.Image;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
@ -26,22 +27,14 @@ import java.nio.ByteBuffer;
|
|||||||
* Usage example:<br>
|
* Usage example:<br>
|
||||||
* <code>
|
* <code>
|
||||||
* Image myImage = ...
|
* Image myImage = ...
|
||||||
* ImageRaster raster = new ImageRaster(myImage);
|
* ImageRaster raster = ImageRaster.create(myImage);
|
||||||
* raster.setPixel(1, 5, ColorRGBA.Green);
|
* raster.setPixel(1, 5, ColorRGBA.Green);
|
||||||
* System.out.println( raster.getPixel(1, 5) ); // Will print [0.0, 1.0, 0.0, 1.0].
|
* System.out.println( raster.getPixel(1, 5) ); // Will print [0.0, 1.0, 0.0, 1.0].
|
||||||
* </code>
|
* </code>
|
||||||
*
|
*
|
||||||
* @author Kirill Vainer
|
* @author Kirill Vainer
|
||||||
*/
|
*/
|
||||||
public final class ImageRaster {
|
public abstract class ImageRaster {
|
||||||
|
|
||||||
private final int[] components = new int[4];
|
|
||||||
private final ByteBuffer buffer;
|
|
||||||
private final Image image;
|
|
||||||
private final ImageCodec codec;
|
|
||||||
private final int width;
|
|
||||||
private final int height;
|
|
||||||
private final byte[] temp;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create new image reader / writer.
|
* Create new image reader / writer.
|
||||||
@ -50,17 +43,8 @@ public final class ImageRaster {
|
|||||||
* @param slice Which slice to use. Only applies to 3D images, 2D image
|
* @param slice Which slice to use. Only applies to 3D images, 2D image
|
||||||
* arrays or cubemaps.
|
* arrays or cubemaps.
|
||||||
*/
|
*/
|
||||||
public ImageRaster(Image image, int slice) {
|
public static ImageRaster create(Image image, int slices) {
|
||||||
this.image = image;
|
return JmeSystem.createImageRaster(image, slices);
|
||||||
this.buffer = image.getData(slice);
|
|
||||||
this.codec = ImageCodec.lookup(image.getFormat());
|
|
||||||
this.width = image.getWidth();
|
|
||||||
this.height = image.getHeight();
|
|
||||||
if (codec instanceof ByteAlignedImageCodec) {
|
|
||||||
this.temp = new byte[codec.bpp];
|
|
||||||
} else {
|
|
||||||
this.temp = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -68,17 +52,14 @@ public final class ImageRaster {
|
|||||||
*
|
*
|
||||||
* @param image The image to read / write to.
|
* @param image The image to read / write to.
|
||||||
*/
|
*/
|
||||||
public ImageRaster(Image image) {
|
public static ImageRaster create(Image image) {
|
||||||
this(image, 0);
|
|
||||||
if (image.getData().size() > 1) {
|
if (image.getData().size() > 1) {
|
||||||
throw new IllegalStateException("Use constructor that takes slices argument to read from multislice image");
|
throw new IllegalStateException("Use constructor that takes slices argument to read from multislice image");
|
||||||
}
|
}
|
||||||
|
return JmeSystem.createImageRaster(image, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void rangeCheck(int x, int y) {
|
public ImageRaster() {
|
||||||
if (x < 0 || y < 0 || x >= width || y >= height) {
|
|
||||||
throw new IllegalArgumentException("x and y must be inside the image dimensions");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -108,37 +89,7 @@ public final class ImageRaster {
|
|||||||
* @param color The color to write.
|
* @param color The color to write.
|
||||||
* @throws IllegalArgumentException If x or y are outside the image dimensions.
|
* @throws IllegalArgumentException If x or y are outside the image dimensions.
|
||||||
*/
|
*/
|
||||||
public void setPixel(int x, int y, ColorRGBA color) {
|
public abstract void setPixel(int x, int y, ColorRGBA color);
|
||||||
rangeCheck(x, y);
|
|
||||||
|
|
||||||
// Check flags for grayscale
|
|
||||||
if ((codec.flags & ImageCodec.FLAG_GRAY) != 0) {
|
|
||||||
float gray = color.r * 0.27f + color.g * 0.67f + color.b * 0.06f;
|
|
||||||
color = new ColorRGBA(gray, gray, gray, color.a);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((codec.flags & ImageCodec.FLAG_F16) != 0) {
|
|
||||||
components[0] = (int) FastMath.convertFloatToHalf(color.a);
|
|
||||||
components[1] = (int) FastMath.convertFloatToHalf(color.r);
|
|
||||||
components[2] = (int) FastMath.convertFloatToHalf(color.g);
|
|
||||||
components[3] = (int) FastMath.convertFloatToHalf(color.b);
|
|
||||||
} else if ((codec.flags & ImageCodec.FLAG_F32) != 0) {
|
|
||||||
components[0] = (int) Float.floatToIntBits(color.a);
|
|
||||||
components[1] = (int) Float.floatToIntBits(color.r);
|
|
||||||
components[2] = (int) Float.floatToIntBits(color.g);
|
|
||||||
components[3] = (int) Float.floatToIntBits(color.b);
|
|
||||||
} else {
|
|
||||||
// Convert color to bits by multiplying by size
|
|
||||||
components[0] = Math.min( (int) (color.a * codec.maxAlpha + 0.5f), codec.maxAlpha);
|
|
||||||
components[1] = Math.min( (int) (color.r * codec.maxRed + 0.5f), codec.maxRed);
|
|
||||||
components[2] = Math.min( (int) (color.g * codec.maxGreen + 0.5f), codec.maxGreen);
|
|
||||||
components[3] = Math.min( (int) (color.b * codec.maxBlue + 0.5f), codec.maxBlue);
|
|
||||||
}
|
|
||||||
|
|
||||||
codec.writeComponents(buffer, x, y, width, components, temp);
|
|
||||||
|
|
||||||
image.setUpdateNeeded();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the color at the given coordinate.
|
* Retrieve the color at the given coordinate.
|
||||||
@ -168,49 +119,7 @@ public final class ImageRaster {
|
|||||||
* with the read color.
|
* with the read color.
|
||||||
* @throws IllegalArgumentException If x or y are outside the image dimensions.
|
* @throws IllegalArgumentException If x or y are outside the image dimensions.
|
||||||
*/
|
*/
|
||||||
public ColorRGBA getPixel(int x, int y, ColorRGBA store) {
|
public abstract ColorRGBA getPixel(int x, int y, ColorRGBA store);
|
||||||
rangeCheck(x, y);
|
|
||||||
|
|
||||||
codec.readComponents(buffer, x, y, width, components, temp);
|
|
||||||
|
|
||||||
if (store == null) {
|
|
||||||
store = new ColorRGBA();
|
|
||||||
}
|
|
||||||
if ((codec.flags & ImageCodec.FLAG_F16) != 0) {
|
|
||||||
store.set(FastMath.convertHalfToFloat((short)components[1]),
|
|
||||||
FastMath.convertHalfToFloat((short)components[2]),
|
|
||||||
FastMath.convertHalfToFloat((short)components[3]),
|
|
||||||
FastMath.convertHalfToFloat((short)components[0]));
|
|
||||||
} else if ((codec.flags & ImageCodec.FLAG_F32) != 0) {
|
|
||||||
store.set(Float.intBitsToFloat((int)components[1]),
|
|
||||||
Float.intBitsToFloat((int)components[2]),
|
|
||||||
Float.intBitsToFloat((int)components[3]),
|
|
||||||
Float.intBitsToFloat((int)components[0]));
|
|
||||||
} else {
|
|
||||||
// Convert to float and divide by bitsize to get into range 0.0 - 1.0.
|
|
||||||
store.set((float)components[1] / codec.maxRed,
|
|
||||||
(float)components[2] / codec.maxGreen,
|
|
||||||
(float)components[3] / codec.maxBlue,
|
|
||||||
(float)components[0] / codec.maxAlpha);
|
|
||||||
}
|
|
||||||
if ((codec.flags & ImageCodec.FLAG_GRAY) != 0) {
|
|
||||||
store.g = store.b = store.r;
|
|
||||||
} else {
|
|
||||||
if (codec.maxRed == 0) {
|
|
||||||
store.r = 1;
|
|
||||||
}
|
|
||||||
if (codec.maxGreen == 0) {
|
|
||||||
store.g = 1;
|
|
||||||
}
|
|
||||||
if (codec.maxBlue == 0) {
|
|
||||||
store.b = 1;
|
|
||||||
}
|
|
||||||
if (codec.maxAlpha == 0) {
|
|
||||||
store.a = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return store;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the color at the given coordinate.
|
* Retrieve the color at the given coordinate.
|
||||||
|
@ -38,6 +38,9 @@ import com.jme3.asset.AssetNotFoundException;
|
|||||||
import com.jme3.asset.DesktopAssetManager;
|
import com.jme3.asset.DesktopAssetManager;
|
||||||
import com.jme3.audio.AudioRenderer;
|
import com.jme3.audio.AudioRenderer;
|
||||||
import com.jme3.system.JmeContext.Type;
|
import com.jme3.system.JmeContext.Type;
|
||||||
|
import com.jme3.texture.Image;
|
||||||
|
import com.jme3.texture.image.DefaultImageRaster;
|
||||||
|
import com.jme3.texture.image.ImageRaster;
|
||||||
import com.jme3.util.Screenshots;
|
import com.jme3.util.Screenshots;
|
||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
@ -70,6 +73,12 @@ public class JmeDesktopSystem extends JmeSystemDelegate {
|
|||||||
ImageIO.write(awtImage, format, outStream);
|
ImageIO.write(awtImage, format, outStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ImageRaster createImageRaster(Image image, int slice) {
|
||||||
|
assert image.getEfficentData() == null;
|
||||||
|
return new DefaultImageRaster(image, slice);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AssetManager newAssetManager() {
|
public AssetManager newAssetManager() {
|
||||||
return new DesktopAssetManager(null);
|
return new DesktopAssetManager(null);
|
||||||
|
@ -8,8 +8,6 @@ import com.jme3.font.Rectangle;
|
|||||||
import com.jme3.material.Material;
|
import com.jme3.material.Material;
|
||||||
import com.jme3.math.ColorRGBA;
|
import com.jme3.math.ColorRGBA;
|
||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
import com.jme3.post.FilterPostProcessor;
|
|
||||||
import com.jme3.post.filters.BloomFilter;
|
|
||||||
import com.jme3.renderer.queue.RenderQueue;
|
import com.jme3.renderer.queue.RenderQueue;
|
||||||
import com.jme3.scene.Geometry;
|
import com.jme3.scene.Geometry;
|
||||||
import com.jme3.scene.shape.Quad;
|
import com.jme3.scene.shape.Quad;
|
||||||
@ -31,8 +29,8 @@ public class TestImageRaster extends SimpleApplication {
|
|||||||
ByteBuffer data = BufferUtils.createByteBuffer( (int)Math.ceil(newFormat.getBitsPerPixel() / 8.0) * width * height);
|
ByteBuffer data = BufferUtils.createByteBuffer( (int)Math.ceil(newFormat.getBitsPerPixel() / 8.0) * width * height);
|
||||||
Image convertedImage = new Image(newFormat, width, height, data);
|
Image convertedImage = new Image(newFormat, width, height, data);
|
||||||
|
|
||||||
ImageRaster sourceReader = new ImageRaster(image);
|
ImageRaster sourceReader = ImageRaster.create(image);
|
||||||
ImageRaster targetWriter = new ImageRaster(convertedImage);
|
ImageRaster targetWriter = ImageRaster.create(convertedImage);
|
||||||
for (int x = 0; x < width; x++) {
|
for (int x = 0; x < width; x++) {
|
||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
ColorRGBA color = sourceReader.getPixel(x, y);
|
ColorRGBA color = sourceReader.getPixel(x, y);
|
||||||
@ -70,7 +68,7 @@ public class TestImageRaster extends SimpleApplication {
|
|||||||
private Image createTestImage() {
|
private Image createTestImage() {
|
||||||
Image testImage = new Image(Format.BGR8, 4, 3, BufferUtils.createByteBuffer(4 * 4 * 3));
|
Image testImage = new Image(Format.BGR8, 4, 3, BufferUtils.createByteBuffer(4 * 4 * 3));
|
||||||
|
|
||||||
ImageRaster io = new ImageRaster(testImage);
|
ImageRaster io = ImageRaster.create(testImage);
|
||||||
io.setPixel(0, 0, ColorRGBA.Black);
|
io.setPixel(0, 0, ColorRGBA.Black);
|
||||||
io.setPixel(1, 0, ColorRGBA.Gray);
|
io.setPixel(1, 0, ColorRGBA.Gray);
|
||||||
io.setPixel(2, 0, ColorRGBA.White);
|
io.setPixel(2, 0, ColorRGBA.White);
|
||||||
@ -101,64 +99,64 @@ public class TestImageRaster extends SimpleApplication {
|
|||||||
Image image = convertImage(originalImage, Format.RGBA32F);
|
Image image = convertImage(originalImage, Format.RGBA32F);
|
||||||
convertAndPutImage(image, 0, 0);
|
convertAndPutImage(image, 0, 0);
|
||||||
|
|
||||||
image = convertImage(originalImage, Format.RGB32F);
|
image = convertImage(image, Format.RGB32F);
|
||||||
convertAndPutImage(image, 5, 0);
|
convertAndPutImage(image, 5, 0);
|
||||||
|
|
||||||
image = convertImage(originalImage, Format.RGBA16F);
|
image = convertImage(image, Format.RGBA16F);
|
||||||
convertAndPutImage(image, 10, 0);
|
convertAndPutImage(image, 10, 0);
|
||||||
|
|
||||||
image = convertImage(originalImage, Format.RGB16F);
|
image = convertImage(image, Format.RGB16F);
|
||||||
convertAndPutImage(image, 15, 0);
|
convertAndPutImage(image, 15, 0);
|
||||||
|
|
||||||
image = convertImage(originalImage, Format.RGB16F_to_RGB9E5);
|
image = convertImage(image, Format.RGB16F_to_RGB9E5);
|
||||||
convertAndPutImage(image, 20, 0);
|
convertAndPutImage(image, 20, 0);
|
||||||
|
|
||||||
image = convertImage(originalImage, Format.RGB16F_to_RGB111110F);
|
image = convertImage(image, Format.RGB16F_to_RGB111110F);
|
||||||
convertAndPutImage(image, 25, 0);
|
convertAndPutImage(image, 25, 0);
|
||||||
|
|
||||||
image = convertImage(originalImage, Format.RGBA16);
|
image = convertImage(image, Format.RGBA16);
|
||||||
convertAndPutImage(image, 0, 5);
|
convertAndPutImage(image, 0, 5);
|
||||||
|
|
||||||
image = convertImage(originalImage, Format.RGB16);
|
image = convertImage(image, Format.RGB16);
|
||||||
convertAndPutImage(image, 5, 5);
|
convertAndPutImage(image, 5, 5);
|
||||||
|
|
||||||
image = convertImage(originalImage, Format.RGBA8);
|
image = convertImage(image, Format.RGBA8);
|
||||||
convertAndPutImage(image, 10, 5);
|
convertAndPutImage(image, 10, 5);
|
||||||
|
|
||||||
image = convertImage(originalImage, Format.RGB8);
|
image = convertImage(image, Format.RGB8);
|
||||||
convertAndPutImage(image, 15, 5);
|
convertAndPutImage(image, 15, 5);
|
||||||
|
|
||||||
image = convertImage(originalImage, Format.ABGR8);
|
image = convertImage(image, Format.ABGR8);
|
||||||
convertAndPutImage(image, 20, 5);
|
convertAndPutImage(image, 20, 5);
|
||||||
|
|
||||||
image = convertImage(originalImage, Format.BGR8);
|
image = convertImage(image, Format.BGR8);
|
||||||
convertAndPutImage(image, 25, 5);
|
convertAndPutImage(image, 25, 5);
|
||||||
|
|
||||||
image = convertImage(originalImage, Format.RGB5A1);
|
image = convertImage(image, Format.RGB5A1);
|
||||||
convertAndPutImage(image, 0, 10);
|
convertAndPutImage(image, 0, 10);
|
||||||
|
|
||||||
image = convertImage(originalImage, Format.ARGB4444);
|
image = convertImage(image, Format.ARGB4444);
|
||||||
convertAndPutImage(image, 5, 10);
|
convertAndPutImage(image, 5, 10);
|
||||||
|
|
||||||
image = convertImage(originalImage, Format.Luminance32F);
|
image = convertImage(image, Format.Luminance32F);
|
||||||
convertAndPutImage(image, 0, 15);
|
convertAndPutImage(image, 0, 15);
|
||||||
|
|
||||||
image = convertImage(originalImage, Format.Luminance16FAlpha16F);
|
image = convertImage(image, Format.Luminance16FAlpha16F);
|
||||||
convertAndPutImage(image, 5, 15);
|
convertAndPutImage(image, 5, 15);
|
||||||
|
|
||||||
image = convertImage(originalImage, Format.Luminance16F);
|
image = convertImage(image, Format.Luminance16F);
|
||||||
convertAndPutImage(image, 10, 15);
|
convertAndPutImage(image, 10, 15);
|
||||||
|
|
||||||
image = convertImage(originalImage, Format.Luminance16Alpha16);
|
image = convertImage(image, Format.Luminance16Alpha16);
|
||||||
convertAndPutImage(image, 15, 15);
|
convertAndPutImage(image, 15, 15);
|
||||||
|
|
||||||
image = convertImage(originalImage, Format.Luminance16);
|
image = convertImage(image, Format.Luminance16);
|
||||||
convertAndPutImage(image, 20, 15);
|
convertAndPutImage(image, 20, 15);
|
||||||
|
|
||||||
image = convertImage(originalImage, Format.Luminance8Alpha8);
|
image = convertImage(image, Format.Luminance8Alpha8);
|
||||||
convertAndPutImage(image, 25, 15);
|
convertAndPutImage(image, 25, 15);
|
||||||
|
|
||||||
image = convertImage(originalImage, Format.Luminance8);
|
image = convertImage(image, Format.Luminance8);
|
||||||
convertAndPutImage(image, 30, 15);
|
convertAndPutImage(image, 30, 15);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user