Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 125 additions & 27 deletions core/src/processing/core/PApplet.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.xml.bind.DatatypeConverter;
// allows us to remove our own MediaTracker code
import javax.swing.ImageIcon;

Expand All @@ -60,7 +61,6 @@

// used by desktopFile() method
import javax.swing.filechooser.FileSystemView;

// loadXML() error handling
import javax.xml.parsers.ParserConfigurationException;

Expand Down Expand Up @@ -5513,6 +5513,22 @@ public PImage loadImage(String filename, String extension) { //, Object params)
g.awaitAsyncSaveCompletion(filename);
}

if(filename.startsWith("file://")){
filename = filename.substring(7);
}

boolean isBase64 = false;
String encoded = null;

if(filename.startsWith("data:image/")) {
String dataURL = filename.substring(0, filename.indexOf(","));
if (dataURL.endsWith("base64")) {
isBase64 = true;
extension = dataURL.substring(dataURL.indexOf("/")+1, dataURL.indexOf(";"));
encoded = filename.substring(dataURL.length()+1);
}
}

if (extension == null) {
String lower = filename.toLowerCase();
int dot = filename.lastIndexOf('.');
Expand All @@ -5535,20 +5551,36 @@ public PImage loadImage(String filename, String extension) { //, Object params)
extension = extension.toLowerCase();

if (extension.equals("tga")) {
try {
PImage image = loadImageTGA(filename);
// if (params != null) {
// image.setParams(g, params);
// }
return image;
} catch (IOException e) {
printStackTrace(e);
return null;

if (isBase64) {
byte bytes[] = DatatypeConverter.parseBase64Binary(encoded);
ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
try {
return loadImageTGA(stream, "base64 image");
} catch (IOException e) {
printStackTrace(e);
return null;
}
}
else {
try {
PImage image = loadImageTGA(filename);
// if (params != null) {
// image.setParams(g, params);
// }
return image;
} catch (IOException e) {
printStackTrace(e);
return null;
}
}

}


if (extension.equals("tif") || extension.equals("tiff")) {
byte bytes[] = loadBytes(filename);

byte bytes[] = isBase64 ? DatatypeConverter.parseBase64Binary(encoded) : loadBytes(filename);
PImage image = (bytes == null) ? null : PImage.loadTIFF(bytes);
// if (params != null) {
// image.setParams(g, params);
Expand All @@ -5563,7 +5595,7 @@ public PImage loadImage(String filename, String extension) { //, Object params)
if (extension.equals("jpg") || extension.equals("jpeg") ||
extension.equals("gif") || extension.equals("png") ||
extension.equals("unknown")) {
byte bytes[] = loadBytes(filename);
byte bytes[] = isBase64 ? DatatypeConverter.parseBase64Binary(encoded) : loadBytes(filename);
if (bytes == null) {
return null;
} else {
Expand All @@ -5574,8 +5606,16 @@ public PImage loadImage(String filename, String extension) { //, Object params)
BufferedImage buffImage = (BufferedImage) awtImage;
int space = buffImage.getColorModel().getColorSpace().getType();
if (space == ColorSpace.TYPE_CMYK) {
System.err.println(filename + " is a CMYK image, " +

if (isBase64) {
System.err.println("The base64 image is a CMYK image, " +
"only RGB images are supported.");
}
else {
System.err.println(filename + " is a CMYK image, " +
"only RGB images are supported.");
}

return null;
/*
// wishful thinking, appears to not be supported
Expand All @@ -5593,8 +5633,15 @@ public PImage loadImage(String filename, String extension) { //, Object params)

PImage image = new PImage(awtImage);
if (image.width == -1) {
System.err.println("The file " + filename +
if (isBase64) {
System.err.println("The base64 image "+
" contains bad image data, or may not be an image.");
}
else {
System.err.println("The file " + filename +
" contains bad image data, or may not be an image.");
}

}

// if it's a .gif image, test to see if it has transparency
Expand All @@ -5619,20 +5666,32 @@ public PImage loadImage(String filename, String extension) { //, Object params)
loadImageFormats = ImageIO.getReaderFormatNames();
}
if (loadImageFormats != null) {
for (int i = 0; i < loadImageFormats.length; i++) {
if (extension.equals(loadImageFormats[i])) {
return loadImageIO(filename);
// PImage image = loadImageIO(filename);
// if (params != null) {
// image.setParams(g, params);
// }
// return image;

if (isBase64) {
byte bytes[] = DatatypeConverter.parseBase64Binary(encoded);
return loadImageIO(bytes);
}
else {
for (int i = 0; i < loadImageFormats.length; i++) {
if (extension.equals(loadImageFormats[i])) {
return loadImageIO(filename);
// PImage image = loadImageIO(filename);
// if (params != null) {
// image.setParams(g, params);
// }
// return image;
}
}
}
}

}
// failed, could not load image after all those attempts
System.err.println("Could not find a method to load " + filename);
if (isBase64) {
System.err.println("Could not find a method to load the base64 image");
}
else {
System.err.println("Could not find a method to load " + filename);
}
return null;
}

Expand Down Expand Up @@ -5747,6 +5806,47 @@ protected PImage loadImageIO(String filename) {
}


/**
* Use Java 1.4 ImageIO methods to load an image.
*/
protected PImage loadImageIO(byte[] bytes) {

ByteArrayInputStream stream = new ByteArrayInputStream(bytes);

try {
BufferedImage bi = ImageIO.read(stream);
PImage outgoing = new PImage(bi.getWidth(), bi.getHeight());
outgoing.parent = this;

bi.getRGB(0, 0, outgoing.width, outgoing.height,
outgoing.pixels, 0, outgoing.width);

// check the alpha for this image
// was gonna call getType() on the image to see if RGB or ARGB,
// but it's not actually useful, since gif images will come through
// as TYPE_BYTE_INDEXED, which means it'll still have to check for
// the transparency. also, would have to iterate through all the other
// types and guess whether alpha was in there, so.. just gonna stick
// with the old method.
outgoing.checkAlpha();

stream.close();
// return the image
return outgoing;

} catch (Exception e) {
printStackTrace(e);
return null;
}
}


protected PImage loadImageTGA(String filename) throws IOException {
InputStream is = createInput(filename);
return loadImageTGA(is, filename);
}


/**
* Targa image loader for RLE-compressed TGA files.
* <p>
Expand All @@ -5761,8 +5861,7 @@ protected PImage loadImageIO(String filename) {
* https://github.com/processing/processing/issues/2096
* Please help!
*/
protected PImage loadImageTGA(String filename) throws IOException {
InputStream is = createInput(filename);
protected PImage loadImageTGA(InputStream is, String filename) throws IOException {
if (is == null) return null;

byte header[] = new byte[18];
Expand Down Expand Up @@ -5952,7 +6051,6 @@ header[17] image descriptor (packed bits)
}



//////////////////////////////////////////////////////////////

// DATA I/O
Expand Down
58 changes: 3 additions & 55 deletions core/src/processing/core/PShape.java
Original file line number Diff line number Diff line change
Expand Up @@ -1888,62 +1888,10 @@ protected void drawPath(PGraphics g) {
g.endShape(close ? CLOSE : OPEN);
}

private void loadImage(PGraphics g){

if(this.imagePath.startsWith("data:image")){
loadBase64Image();
}

if(this.imagePath.startsWith("file://")){
loadFileSystemImage(g);
}
this.imagePath = null;
}

private void loadFileSystemImage(PGraphics g){
imagePath = imagePath.substring(7);
PImage loadedImage = g.parent.loadImage(imagePath);
if(loadedImage == null){
System.err.println("Error loading image file: " + imagePath);
}else{
setTexture(loadedImage);
}
}

private void loadBase64Image(){
String[] parts = this.imagePath.split(";base64,");
String extension = parts[0].substring(11);
String encodedData = parts[1];

byte[] decodedBytes = DatatypeConverter.parseBase64Binary(encodedData);

if(decodedBytes == null){
System.err.println("Decode Error on image: " + imagePath.substring(0, 20));
return;
}

Image awtImage = new ImageIcon(decodedBytes).getImage();

if (awtImage instanceof BufferedImage) {
BufferedImage buffImage = (BufferedImage) awtImage;
int space = buffImage.getColorModel().getColorSpace().getType();
if (space == ColorSpace.TYPE_CMYK) {
return;
}
}

PImage loadedImage = new PImage(awtImage);
if (loadedImage.width == -1) {
// error...
}

// if it's a .gif image, test to see if it has transparency
if (extension.equals("gif") || extension.equals("png") ||
extension.equals("unknown")) {
loadedImage.checkAlpha();
}

protected void loadImage(PGraphics g){
PImage loadedImage = g.parent.loadImage(this.imagePath);
setTexture(loadedImage);
this.imagePath = null;
}

// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Expand Down