Skip to content

Commit

Permalink
Added methods to copy a pixel by changing one component.
Browse files Browse the repository at this point in the history
  • Loading branch information
sksamuel committed Feb 26, 2022
1 parent d68f633 commit de08bb5
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 18 deletions.
12 changes: 6 additions & 6 deletions buildSrc/src/main/kotlin/Libs.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
object Libs {

const val kotlinVersion = "1.5.20"
const val kotlinVersion = "1.6.10"

const val org = "com.sksamuel.scrimage"


object TwelveMonkeys {
private const val Version = "3.7.0"
private const val Version = "3.8.2"
const val imageIoCore = "com.twelvemonkeys.imageio:imageio-core:$Version"
const val jpeg = "com.twelvemonkeys.imageio:imageio-jpeg:$Version"
const val pcx = "com.twelvemonkeys.imageio:imageio-pcx:$Version"
Expand All @@ -23,10 +23,10 @@ object Libs {
}

object Kotest {
private const val version = "4.6.3"
const val assertions = "io.kotest:kotest-assertions-core-jvm:$version"
const val api = "io.kotest:kotest-framework-api:$version"
const val junit5 = "io.kotest:kotest-runner-junit5-jvm:$version"
private const val version = "5.1.0"
const val assertions = "io.kotest:kotest-assertions-core:$version"
const val datatest = "io.kotest:kotest-framework-datatest:$version"
const val junit5 = "io.kotest:kotest-runner-junit5:$version"
}

object Drewnoaks {
Expand Down
21 changes: 17 additions & 4 deletions scrimage-core/src/main/java/com/sksamuel/scrimage/AwtImage.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@
import com.sksamuel.scrimage.scaling.ScrimageNearestNeighbourScale;
import com.sksamuel.scrimage.subpixel.LinearSubpixelInterpolator;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferInt;
Expand All @@ -31,7 +29,9 @@

/**
* Wraps an AWT BufferedImage with some basic helper functions related to sizes, pixels etc.
*
* It also includes methods to write out the image.
*
* None of the operations in this class will mutate the underlying awt buffer.
*/
public class AwtImage {
Expand Down Expand Up @@ -562,8 +562,9 @@ public boolean hasAlpha() {
/**
* Returns true if this image supports transparency/alpha in its underlying data model.
*/
@Deprecated()
public boolean hasTransparency() {
return awt().getColorModel().hasAlpha();
return hasAlpha();
}

/**
Expand Down Expand Up @@ -612,4 +613,16 @@ public WriteContext forWriter(ImageWriter writer) {
public ByteArrayInputStream stream(ImageWriter writer) throws IOException {
return forWriter(writer).stream();
}

/**
* Returns a copy of this image with the backing image type set to the given value.
*/
public AwtImage clone(int imageType) {
if (imageType <= 0) throw new IllegalArgumentException("Image type must be > 0");
BufferedImage target = new BufferedImage(awt.getWidth(null), awt.getHeight(null), imageType);
Graphics g2 = target.getGraphics();
g2.drawImage(awt, 0, 0, null);
g2.dispose();
return new AwtImage(target);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,7 @@ public static ImmutableImage fromAwt(BufferedImage awt, int type) {
if (imageType == 0) {
imageType = BufferedImage.TYPE_INT_ARGB;
}
BufferedImage target = new BufferedImage(awt.getWidth(null), awt.getHeight(null), imageType);
Graphics g2 = target.getGraphics();
g2.drawImage(awt, 0, 0, null);
g2.dispose();
return new ImmutableImage(target, ImageMetadata.empty);
return wrapAwt(new AwtImage(awt).clone(imageType).awt());
}

/**
Expand Down Expand Up @@ -239,7 +235,7 @@ public static ImmutableImage create(int width, int height, int type) {
BufferedImage target = new BufferedImage(width, height, type);
return new ImmutableImage(target, ImageMetadata.empty);
}

/**
* Create a new ImmutableImage that is the given dimension with no initialization.
* This will usually result in a default black background (all pixel data defaulting to zeroes)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,51 @@ public int toARGBInt() {
return argb;
}

/**
* Returns a copy of this pixel, with the same red, green, blue values, but with alpha
* set to the given value.
*/
public Pixel alpha(int a) {
return new Pixel(x, y, red(), green(), blue(), a);
}

/**
* Returns a copy of this pixel, with the same red, green, blue values, but with alpha
* set to fully opaque (255).
*/
public Pixel noalpha() {
return alpha(255);
}

/**
* Returns a copy of this pixel, with the same red, green, blue values, but with alpha
* set to fully transparent (0).
*/
public Pixel fullalpha() {
return alpha(0);
}

/**
* Returns a copy of this pixel with the red component set to the given value.
*/
public Pixel red(int r) {
return new Pixel(x, y, r, green(), blue(), alpha());
}

/**
* Returns a copy of this pixel with the green component set to the given value.
*/
public Pixel green(int g) {
return new Pixel(x, y, red(), g, blue(), alpha());
}

/**
* Returns a copy of this pixel with the blue component set to the given value.
*/
public Pixel blue(int b) {
return new Pixel(x, y, red(), green(), b, alpha());
}

/**
* Returns this pixel as an array of ARGB values.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.sksamuel.scrimage.core

import com.sksamuel.scrimage.angles.Degrees
import io.kotest.core.datatest.forAll
import io.kotest.core.spec.style.FunSpec
import io.kotest.datatest.withData
import io.kotest.matchers.doubles.plusOrMinus
import io.kotest.matchers.shouldBe

Expand All @@ -12,7 +12,7 @@ class AnglesTest : FunSpec() {
data class DegreeConversion(val input: Int, val output: Double)

context("degrees to rads") {
forAll(
withData(
DegreeConversion(45, 0.785398),
DegreeConversion(180, 3.14159),
DegreeConversion(360, 6.28319),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.sksamuel.scrimage.core

import com.sksamuel.scrimage.ImmutableImage
import com.sksamuel.scrimage.MutableImage
import io.kotest.core.spec.style.FunSpec
import java.awt.image.BufferedImage

class Issue239Test : FunSpec({

// https://github.com/sksamuel/scrimage/issues/239
test("Pixels with alpha 0 turns black #239") {
val image = ImmutableImage.loader().fromResource("/issue239.jpg")
val mutImage = MutableImage(image.copy(BufferedImage.TYPE_INT_ARGB).awt())
for (pixel in mutImage.pixels()) {
if (pixel.red() > 240 && pixel.green() > 240 && pixel.blue() > 240) {
val newPixel = pixel.fullalpha().red(125).blue(0).green(0)
mutImage.setPixel(newPixel)
}
}

// issue was that the source image did not have alpha enabled
}

})
Binary file added scrimage-tests/src/test/resources/issue239.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit de08bb5

Please sign in to comment.