mirror of
https://gitlab.com/AutumnMeowMeow/jexer
synced 2024-09-19 11:50:19 -06:00
#102 Pass indexed from TImage to HQSixelEncoder
This commit is contained in:
parent
9e824d90b7
commit
a427368227
5 changed files with 110 additions and 33 deletions
|
@ -99,6 +99,11 @@ public class TImage extends TWidget implements EditMenuUser {
|
||||||
*/
|
*/
|
||||||
private BufferedImage image;
|
private BufferedImage image;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If false, the image is fully opaque.
|
||||||
|
*/
|
||||||
|
private boolean maybeTransparent = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The original image from construction time.
|
* The original image from construction time.
|
||||||
*/
|
*/
|
||||||
|
@ -463,6 +468,7 @@ public class TImage extends TWidget implements EditMenuUser {
|
||||||
* @param always if true, always resize the cells
|
* @param always if true, always resize the cells
|
||||||
*/
|
*/
|
||||||
private void sizeToImage(final boolean always) {
|
private void sizeToImage(final boolean always) {
|
||||||
|
|
||||||
scaleBackColor = getApplication().getBackend().attrToBackgroundColor(getWindow().getBackground());
|
scaleBackColor = getApplication().getBackend().attrToBackgroundColor(getWindow().getBackground());
|
||||||
|
|
||||||
int textWidth = getScreen().getTextWidth();
|
int textWidth = getScreen().getTextWidth();
|
||||||
|
@ -513,20 +519,22 @@ public class TImage extends TWidget implements EditMenuUser {
|
||||||
cell.setTo(getWindow().getBackground());
|
cell.setTo(getWindow().getBackground());
|
||||||
|
|
||||||
// Render over a full-cell-size image.
|
// Render over a full-cell-size image.
|
||||||
BufferedImage newImage = new BufferedImage(textWidth,
|
BufferedImage newImage = ImageUtils.createImage(image,
|
||||||
textHeight, BufferedImage.TYPE_INT_ARGB);
|
textWidth, textHeight);
|
||||||
Graphics gr = newImage.getGraphics();
|
Graphics gr = newImage.getGraphics();
|
||||||
BufferedImage subImage = image.getSubimage(x * textWidth,
|
BufferedImage subImage = image.getSubimage(x * textWidth,
|
||||||
y * textHeight, width, height);
|
y * textHeight, width, height);
|
||||||
gr.drawImage(subImage, 0, 0, null, null);
|
gr.drawImage(subImage, 0, 0, null, null);
|
||||||
gr.dispose();
|
gr.dispose();
|
||||||
|
|
||||||
if (!ImageUtils.isFullyTransparent(newImage)) {
|
cell.setImage(newImage);
|
||||||
cell.setImage(newImage);
|
if (!maybeTransparent) {
|
||||||
|
cell.setOpaqueImage();
|
||||||
|
} else if (!ImageUtils.isFullyTransparent(newImage)) {
|
||||||
cell.flattenImage(false, getApplication().getBackend());
|
cell.flattenImage(false, getApplication().getBackend());
|
||||||
imageId++;
|
|
||||||
cell.setImageId(imageId & 0x7FFFFFFF);
|
|
||||||
}
|
}
|
||||||
|
imageId++;
|
||||||
|
cell.setImageId(imageId & 0x7FFFFFFF);
|
||||||
cells[x][y] = cell;
|
cells[x][y] = cell;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -649,7 +657,20 @@ public class TImage extends TWidget implements EditMenuUser {
|
||||||
* @param image the new image
|
* @param image the new image
|
||||||
*/
|
*/
|
||||||
public void setImage(final BufferedImage image) {
|
public void setImage(final BufferedImage image) {
|
||||||
|
setImage(image, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the raw image, and reprocess to make the visible image.
|
||||||
|
*
|
||||||
|
* @param image the new image
|
||||||
|
* @param maybeTransparent if false, the image is fully opaque
|
||||||
|
*/
|
||||||
|
public void setImage(final BufferedImage image,
|
||||||
|
final boolean maybeTransparent) {
|
||||||
|
|
||||||
this.originalImage = image;
|
this.originalImage = image;
|
||||||
|
this.maybeTransparent = maybeTransparent;
|
||||||
this.image = null;
|
this.image = null;
|
||||||
sizeToImage(true);
|
sizeToImage(true);
|
||||||
if (animation != null) {
|
if (animation != null) {
|
||||||
|
@ -807,14 +828,13 @@ public class TImage extends TWidget implements EditMenuUser {
|
||||||
case NONE:
|
case NONE:
|
||||||
destWidth = (int) (image.getWidth() * factor);
|
destWidth = (int) (image.getWidth() * factor);
|
||||||
destHeight = (int) (image.getHeight() * factor);
|
destHeight = (int) (image.getHeight() * factor);
|
||||||
newImage = new BufferedImage(Math.max(1, destWidth),
|
newImage = ImageUtils.createImage(image,
|
||||||
Math.max(1, destHeight), BufferedImage.TYPE_INT_ARGB);
|
Math.max(1, destWidth), Math.max(1, destHeight));
|
||||||
break;
|
break;
|
||||||
case STRETCH:
|
case STRETCH:
|
||||||
destWidth = Math.max(1, width) * textWidth;
|
destWidth = Math.max(1, width) * textWidth;
|
||||||
destHeight = Math.max(1, height) * textHeight;
|
destHeight = Math.max(1, height) * textHeight;
|
||||||
newImage = new BufferedImage(destWidth, destHeight,
|
newImage = ImageUtils.createImage(image, destWidth, destHeight);
|
||||||
BufferedImage.TYPE_INT_ARGB);
|
|
||||||
break;
|
break;
|
||||||
case SCALE:
|
case SCALE:
|
||||||
double a = (double) image.getWidth() / image.getHeight();
|
double a = (double) image.getWidth() / image.getHeight();
|
||||||
|
@ -851,8 +871,9 @@ public class TImage extends TWidget implements EditMenuUser {
|
||||||
"x" + destHeight + ", X offset " + x);
|
"x" + destHeight + ", X offset " + x);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
newImage = new BufferedImage(Math.max(1, width) * textWidth,
|
newImage = ImageUtils.createImage(image,
|
||||||
Math.max(1, height) * textHeight, BufferedImage.TYPE_INT_ARGB);
|
Math.max(1, width) * textWidth,
|
||||||
|
Math.max(1, height) * textHeight);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -896,8 +917,8 @@ public class TImage extends TWidget implements EditMenuUser {
|
||||||
|
|
||||||
if (clockwise % 4 == 1) {
|
if (clockwise % 4 == 1) {
|
||||||
// 90 degrees clockwise
|
// 90 degrees clockwise
|
||||||
newImage = new BufferedImage(image.getHeight(), image.getWidth(),
|
newImage = ImageUtils.createImage(image,
|
||||||
BufferedImage.TYPE_INT_ARGB);
|
image.getHeight(), image.getWidth());
|
||||||
for (int x = 0; x < image.getWidth(); x++) {
|
for (int x = 0; x < image.getWidth(); x++) {
|
||||||
for (int y = 0; y < image.getHeight(); y++) {
|
for (int y = 0; y < image.getHeight(); y++) {
|
||||||
newImage.setRGB(y, x,
|
newImage.setRGB(y, x,
|
||||||
|
@ -906,8 +927,8 @@ public class TImage extends TWidget implements EditMenuUser {
|
||||||
}
|
}
|
||||||
} else if (clockwise % 4 == 2) {
|
} else if (clockwise % 4 == 2) {
|
||||||
// 180 degrees clockwise
|
// 180 degrees clockwise
|
||||||
newImage = new BufferedImage(image.getWidth(), image.getHeight(),
|
newImage = ImageUtils.createImage(image,
|
||||||
BufferedImage.TYPE_INT_ARGB);
|
image.getWidth(), image.getHeight());
|
||||||
for (int x = 0; x < image.getWidth(); x++) {
|
for (int x = 0; x < image.getWidth(); x++) {
|
||||||
for (int y = 0; y < image.getHeight(); y++) {
|
for (int y = 0; y < image.getHeight(); y++) {
|
||||||
newImage.setRGB(x, y,
|
newImage.setRGB(x, y,
|
||||||
|
@ -917,8 +938,8 @@ public class TImage extends TWidget implements EditMenuUser {
|
||||||
}
|
}
|
||||||
} else if (clockwise % 4 == 3) {
|
} else if (clockwise % 4 == 3) {
|
||||||
// 270 degrees clockwise
|
// 270 degrees clockwise
|
||||||
newImage = new BufferedImage(image.getHeight(), image.getWidth(),
|
newImage = ImageUtils.createImage(image,
|
||||||
BufferedImage.TYPE_INT_ARGB);
|
image.getHeight(), image.getWidth());
|
||||||
for (int x = 0; x < image.getWidth(); x++) {
|
for (int x = 0; x < image.getWidth(); x++) {
|
||||||
for (int y = 0; y < image.getHeight(); y++) {
|
for (int y = 0; y < image.getHeight(); y++) {
|
||||||
newImage.setRGB(y, x,
|
newImage.setRGB(y, x,
|
||||||
|
|
|
@ -59,6 +59,7 @@ import javax.imageio.ImageIO;
|
||||||
import jexer.bits.Cell;
|
import jexer.bits.Cell;
|
||||||
import jexer.bits.CellAttributes;
|
import jexer.bits.CellAttributes;
|
||||||
import jexer.bits.Color;
|
import jexer.bits.Color;
|
||||||
|
import jexer.bits.ImageUtils;
|
||||||
import jexer.bits.StringUtils;
|
import jexer.bits.StringUtils;
|
||||||
import jexer.event.TCommandEvent;
|
import jexer.event.TCommandEvent;
|
||||||
import jexer.event.TInputEvent;
|
import jexer.event.TInputEvent;
|
||||||
|
@ -3629,8 +3630,8 @@ public class ECMA48Terminal extends LogicalScreen
|
||||||
|
|
||||||
// The final image will be 1000 x 1000 or less.
|
// The final image will be 1000 x 1000 or less.
|
||||||
BufferedImage cellsImage = cellsToImage(cells);
|
BufferedImage cellsImage = cellsToImage(cells);
|
||||||
BufferedImage fullImage = new BufferedImage(maxPixelX,
|
BufferedImage fullImage = ImageUtils.createImage(cellsImage,
|
||||||
maxPixelY, BufferedImage.TYPE_INT_ARGB);
|
maxPixelX, maxPixelY);
|
||||||
Graphics gr = fullImage.getGraphics();
|
Graphics gr = fullImage.getGraphics();
|
||||||
gr.drawImage(cellsImage, pixelX, pixelY, null);
|
gr.drawImage(cellsImage, pixelX, pixelY, null);
|
||||||
gr.dispose();
|
gr.dispose();
|
||||||
|
@ -3673,8 +3674,8 @@ public class ECMA48Terminal extends LogicalScreen
|
||||||
totalWidth += cells.get(i).getImage().getWidth();
|
totalWidth += cells.get(i).getImage().getWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferedImage image = new BufferedImage(fullWidth,
|
BufferedImage image = ImageUtils.createImage(cells.get(0).getImage(),
|
||||||
fullHeight, BufferedImage.TYPE_INT_ARGB);
|
fullWidth, fullHeight);
|
||||||
|
|
||||||
int [] rgbArray;
|
int [] rgbArray;
|
||||||
for (int i = 0; i < cells.size() - 1; i++) {
|
for (int i = 0; i < cells.size() - 1; i++) {
|
||||||
|
@ -3780,8 +3781,8 @@ public class ECMA48Terminal extends LogicalScreen
|
||||||
) {
|
) {
|
||||||
// Rescale the image to fit the text cells it is going into.
|
// Rescale the image to fit the text cells it is going into.
|
||||||
BufferedImage newImage;
|
BufferedImage newImage;
|
||||||
newImage = new BufferedImage(cells.size() * getTextWidth(),
|
newImage = ImageUtils.createImage(image,
|
||||||
getTextHeight(), BufferedImage.TYPE_INT_ARGB);
|
cells.size() * getTextWidth(), getTextHeight());
|
||||||
|
|
||||||
Graphics gr = newImage.getGraphics();
|
Graphics gr = newImage.getGraphics();
|
||||||
if (gr instanceof Graphics2D) {
|
if (gr instanceof Graphics2D) {
|
||||||
|
|
|
@ -1702,17 +1702,23 @@ public class HQSixelEncoder implements SixelEncoder {
|
||||||
* Emit the sixel palette.
|
* Emit the sixel palette.
|
||||||
*
|
*
|
||||||
* @param sb the StringBuilder to append to
|
* @param sb the StringBuilder to append to
|
||||||
* @return the string to emit to an ANSI / ECMA-style terminal
|
|
||||||
*/
|
*/
|
||||||
public String emitPalette(final StringBuilder sb) {
|
public void emitPalette(final StringBuilder sb) {
|
||||||
for (int i = 0; i < sixelColors.size(); i++) {
|
for (int i = 0; i < sixelColors.size(); i++) {
|
||||||
int sixelColor = sixelColors.get(i);
|
int sixelColor = sixelColors.get(i);
|
||||||
sb.append(String.format("#%d;2;%d;%d;%d", i,
|
int red = ((sixelColor >>> 16) & 0xFF);
|
||||||
((sixelColor >>> 16) & 0xFF),
|
int green = ((sixelColor >>> 8) & 0xFF);
|
||||||
((sixelColor >>> 8) & 0xFF),
|
int blue = ( sixelColor & 0xFF);
|
||||||
( sixelColor & 0xFF)));
|
|
||||||
|
sb.append("#");
|
||||||
|
sb.append(Integer.toString(i));
|
||||||
|
sb.append(";2;");
|
||||||
|
sb.append(Integer.toString(red));
|
||||||
|
sb.append(";");
|
||||||
|
sb.append(Integer.toString(green));
|
||||||
|
sb.append(";");
|
||||||
|
sb.append(Integer.toString(blue));
|
||||||
}
|
}
|
||||||
return sb.toString();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
package jexer.bits;
|
package jexer.bits;
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.awt.image.IndexColorModel;
|
||||||
import jexer.backend.Backend;
|
import jexer.backend.Backend;
|
||||||
import jexer.backend.GlyphMaker;
|
import jexer.backend.GlyphMaker;
|
||||||
import jexer.backend.SwingTerminal;
|
import jexer.backend.SwingTerminal;
|
||||||
|
@ -227,8 +228,8 @@ public class Cell extends CellAttributes {
|
||||||
|
|
||||||
int textWidth = image.getWidth();
|
int textWidth = image.getWidth();
|
||||||
int textHeight = image.getHeight();
|
int textHeight = image.getHeight();
|
||||||
BufferedImage newImage = new BufferedImage(textWidth,
|
BufferedImage newImage = ImageUtils.createImage(image, textWidth,
|
||||||
textHeight, BufferedImage.TYPE_INT_ARGB);
|
textHeight);
|
||||||
java.awt.Graphics gr = newImage.getGraphics();
|
java.awt.Graphics gr = newImage.getGraphics();
|
||||||
if (invertedImage != null) {
|
if (invertedImage != null) {
|
||||||
assert (image != null);
|
assert (image != null);
|
||||||
|
@ -315,8 +316,12 @@ public class Cell extends CellAttributes {
|
||||||
|
|
||||||
int textWidth = image.getWidth();
|
int textWidth = image.getWidth();
|
||||||
int textHeight = image.getHeight();
|
int textHeight = image.getHeight();
|
||||||
|
/*
|
||||||
BufferedImage newImage = new BufferedImage(textWidth,
|
BufferedImage newImage = new BufferedImage(textWidth,
|
||||||
textHeight, BufferedImage.TYPE_INT_ARGB);
|
textHeight, BufferedImage.TYPE_INT_ARGB);
|
||||||
|
*/
|
||||||
|
BufferedImage newImage = ImageUtils.createImage(image,
|
||||||
|
textWidth, textHeight);
|
||||||
java.awt.Graphics gr = newImage.getGraphics();
|
java.awt.Graphics gr = newImage.getGraphics();
|
||||||
if (backend != null) {
|
if (backend != null) {
|
||||||
gr.setColor(backend.attrToBackgroundColor(this));
|
gr.setColor(backend.attrToBackgroundColor(this));
|
||||||
|
@ -356,8 +361,12 @@ public class Cell extends CellAttributes {
|
||||||
|
|
||||||
int textWidth = image.getWidth();
|
int textWidth = image.getWidth();
|
||||||
int textHeight = image.getHeight();
|
int textHeight = image.getHeight();
|
||||||
|
/*
|
||||||
BufferedImage newImage = new BufferedImage(textWidth,
|
BufferedImage newImage = new BufferedImage(textWidth,
|
||||||
textHeight, BufferedImage.TYPE_INT_ARGB);
|
textHeight, BufferedImage.TYPE_INT_ARGB);
|
||||||
|
*/
|
||||||
|
BufferedImage newImage = ImageUtils.createImage(image,
|
||||||
|
textWidth, textHeight);
|
||||||
java.awt.Graphics gr = newImage.getGraphics();
|
java.awt.Graphics gr = newImage.getGraphics();
|
||||||
gr.setColor(background);
|
gr.setColor(background);
|
||||||
|
|
||||||
|
@ -690,6 +699,15 @@ public class Cell extends CellAttributes {
|
||||||
if ((invertedImage != null) && (that.invertedImage == null)) {
|
if ((invertedImage != null) && (that.invertedImage == null)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (image.getType() != that.image.getType()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((image.getColorModel() instanceof IndexColorModel)
|
||||||
|
&& (that.image.getColorModel() instanceof IndexColorModel)
|
||||||
|
&& image.getColorModel() != that.image.getColorModel()
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// Either both objects have their image inverted, or neither do.
|
// Either both objects have their image inverted, or neither do.
|
||||||
if ((imageId != 0) && (that.imageId != 0)) {
|
if ((imageId != 0) && (that.imageId != 0)) {
|
||||||
return (imageId == that.imageId);
|
return (imageId == that.imageId);
|
||||||
|
|
|
@ -30,6 +30,10 @@ package jexer.bits;
|
||||||
|
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.awt.image.ColorModel;
|
||||||
|
// import java.awt.image.DataBuffer;
|
||||||
|
import java.awt.image.IndexColorModel;
|
||||||
|
// import java.awt.image.Raster;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
@ -509,4 +513,31 @@ public class ImageUtils {
|
||||||
return (rgbRed << 16) | (rgbGreen << 8) | rgbBlue;
|
return (rgbRed << 16) | (rgbGreen << 8) | rgbBlue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a BufferedImage using the same color model as another image.
|
||||||
|
*
|
||||||
|
* @param image the original image
|
||||||
|
* @param width the width of the new image
|
||||||
|
* @param height the height of the new image
|
||||||
|
* @return the new image
|
||||||
|
*/
|
||||||
|
public static BufferedImage createImage(final BufferedImage image,
|
||||||
|
final int width, final int height) {
|
||||||
|
|
||||||
|
if (image.getType() == BufferedImage.TYPE_INT_ARGB) {
|
||||||
|
return new BufferedImage(width, height,
|
||||||
|
BufferedImage.TYPE_INT_ARGB);
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorModel colorModel = image.getColorModel();
|
||||||
|
if (colorModel instanceof IndexColorModel) {
|
||||||
|
IndexColorModel indexModel = (IndexColorModel) colorModel;
|
||||||
|
return new BufferedImage(width, height, image.getType(),
|
||||||
|
indexModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: ARGB
|
||||||
|
return new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue