Skip to content

Add the ability to choose the interpolation mode when resizing an image #1057

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
18 changes: 14 additions & 4 deletions core/src/processing/awt/ShimAWT.java
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ static public Object getNativeImage(PImage img) {
}


static public void resizeImage(PImage img, int w, int h) { // ignore
static public void resizeImage(PImage img, int w, int h, int interpolationMode) { // ignore
if (w <= 0 && h <= 0) {
throw new IllegalArgumentException("width or height must be > 0 for resize");
}
Expand All @@ -251,7 +251,8 @@ static public void resizeImage(PImage img, int w, int h) { // ignore
}

BufferedImage bimg =
shrinkImage((BufferedImage) img.getNative(), w*img.pixelDensity, h*img.pixelDensity);
shrinkImage((BufferedImage) img.getNative(), w*img.pixelDensity,
h*img.pixelDensity, interpolationMode);

PImage temp = new PImageAWT(bimg);
img.pixelWidth = temp.width;
Expand All @@ -274,7 +275,8 @@ static public void resizeImage(PImage img, int w, int h) { // ignore
// plus a fix to deal with an infinite loop if images are expanded.
// https://github.com/processing/processing/issues/1501
static private BufferedImage shrinkImage(BufferedImage img,
int targetWidth, int targetHeight) {
int targetWidth, int targetHeight,
int interpolationMode) {
int type = (img.getTransparency() == Transparency.OPAQUE) ?
BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage outgoing = img;
Expand Down Expand Up @@ -313,8 +315,16 @@ static private BufferedImage shrinkImage(BufferedImage img,
scratchImage = new BufferedImage(w, h, type);
g2 = scratchImage.createGraphics();
}
// convert the passed int value of interpolationMode to the object expected
// by setRenderingHint
Object interpolationModeValue = switch(interpolationMode) {
case 0 -> RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
//case 1 is the same as the default
case 2 -> RenderingHints.VALUE_INTERPOLATION_BICUBIC;
default -> RenderingHints.VALUE_INTERPOLATION_BILINEAR;
};
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
interpolationModeValue);
g2.drawImage(outgoing, 0, 0, w, h, 0, 0, prevW, prevH, null);
prevW = w;
prevH = h;
Expand Down
5 changes: 5 additions & 0 deletions core/src/processing/core/PConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,11 @@ public interface PConstants {
int WAIT = Cursor.WAIT_CURSOR;


// image interpolation modes
int NEAREST_NEIGHBOR = 0;
int BILINEAR = 1;
int BICUBIC = 2;

// hints - hint values are positive for the alternate version,
// negative of the same value returns to the normal/default state

Expand Down
30 changes: 28 additions & 2 deletions core/src/processing/core/PImage.java
Original file line number Diff line number Diff line change
Expand Up @@ -497,11 +497,37 @@ public Object clone() throws CloneNotSupportedException { // ignore
* @usage web_application
* @param w the resized image width
* @param h the resized image height
* @param interpolationMode the type of interpolation that should be used when resizing the image
* @see PImage#get(int, int, int, int)
*/
public void resize(int w, int h) { // ignore
public void resize(int w, int h,int interpolationMode) { // ignore
//throw new RuntimeException("resize() not implemented for this PImage type");
ShimAWT.resizeImage(this, w, h);
ShimAWT.resizeImage(this, w, h, interpolationMode);
}

/**
*
* Resize the image to a new width and height. To make the image scale
* proportionally, use 0 as the value for the <b>wide</b> or <b>high</b>
* parameter. For instance, to make the width of an image 150 pixels, and
* change the height using the same proportion, use <b>resize(150, 0)</b>.<br />
* <br />
* Even though a PGraphics is technically a <b>PImage</b>, it is not possible to
* rescale the image data found in a <b>PGraphics</b>. (It's simply not possible
* to do this consistently across renderers: technically infeasible with
* P3D, or what would it even do with PDF?) If you want to resize <b>PGraphics</b>
* content, first get a copy of its image data using the <b>get()</b>
* method, and call <b>resize()</b> on the PImage that is returned.
*
* @webref pimage:method
* @webBrief Resize the image to a new width and height
* @usage web_application
* @param w the resized image width
* @param h the resized image height
* @see PImage#get(int, int, int, int)
*/
public void resize(int w, int h) { // ignore
resize(w, h, 1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be good if you used the constant that you defined here for clarity

}


Expand Down