我想知道如何将变量蒙版应用于Java中的图像透明度(可能是使用缓冲图像)。因此,例如,我想应用如下掩码:
对于如下图像:
为了得到:
透明度因渐变而不仅仅是颜色而变得很重要,因为我希望能够做到这一点:
通过手动设置每个像素的透明度值,我发现了一种非常缓慢的实现方法,但正如我所说,它的速度非常慢。我应该怎么看才能做到这一点?或者我应该在Java中做到这一点?我最近开始了解python,所以如果有人认为用特定的python模块尝试这种事情会更好,那也是有用的信息。
提前感谢!
答案 0 :(得分:0)
这是获得透明蒙版的一种方法。
GradientMask.java:
import Utilities.*;
import javax.swing.*;
import javax.imageio.*;
import java.awt.*;
import java.awt.image.*;
import java.io.*;
public class GradientMask {
public static void main(String[] args) throws Exception{
JFrame Main = new JFrame("Gradient Mask");
JLabel imageLayer = new JLabel();
JLabel maskLayer = new JLabel();
BufferedImage image = ImageIO.read(new File("C:\\Users\\"+System.getenv("username")+"\\Desktop\\Cat Image.jpg"));
BufferedImage gradientMask = new GradientImage(image.getWidth(), image.getHeight(), new Color[]{new Color(255, 255, 255, 125), Color.BLACK}, GradientImage.RADIAL_FROM_CENTER).getImage();
Main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Main.setBounds(100, 50, image.getWidth(), image.getHeight());
imageLayer.setBounds(0, 0, Main.getWidth(), Main.getHeight());
maskLayer.setBounds(0, 0, Main.getWidth(), Main.getHeight());
imageLayer.setIcon(new ImageIcon((Image) image));
maskLayer.setIcon(new ImageIcon((Image) gradientMask));
Main.getContentPane().add(imageLayer);
imageLayer.add(maskLayer);
Main.setVisible(true);
}
}
GradientImage.java:
package Utilities;
import java.awt.*;
import java.awt.image.*;
public class GradientImage {
public final static int LINEAR_LEFT_TO_RIGHT = 1;
public final static int LINEAR_RIGHT_TO_LEFT = 2;
public final static int LINEAR_TOP_TO_BOTTOM = 3;
public final static int LINEAR_BOTTOM_TO_TOP = 4;
public final static int LINEAR_DIAGONAL_UP = 5;
public final static int LINEAR_DIAGONAL_DOWN = 6;
public final static int RADIAL_FROM_TOP_LEFT_CORNER = 7;
public final static int RADIAL_FROM_BOTTOM_LEFT_CORNER = 8;
public final static int RADIAL_FROM_TOP_RIGHT_CORNER = 9;
public final static int RADIAL_FROM_BOTTOM_RIGHT_CORNER = 10;
public final static int RADIAL_FROM_CENTER = 11;
public final static int RADIAL_FROM_CORNERS = 12;
public final static int PATH_FROM_CENTER = 13;
public final static int PATH_FROM_TOP_LEFT_CORNER = 14;
public final static int PATH_FROM_TOP_RIGHT_CORNER = 15;
public final static int PATH_FROM_BOTTOM_LEFT_CORNER = 16;
public final static int PATH_FROM_BOTTOM_RIGHT_CORNER = 17;
public final static int LINEAR_FROM_TOP_RIGHT_CORNER = 18;
public final static int LINEAR_FROM_TOP_LEFT_CORNER = 19;
public final static int LINEAR_FROM_BOTTOM_RIGHT_CORNER = 20;
public final static int LINEAR_FROM_BOTTOM_LEFT_CORNER = 21;
public final static int LINEAR_FROM_CENTER = 22;
public final static int LINEAR_FROM_CORNERS = 23;
public final static int PATH_FROM_CORNERS = 24;
private BufferedImage image = null;
private BufferedImage circleImage = null;
private int[] pixels;
private int[] circlePixels;
private int[] positions;
private Color[] colors;
private int[] rgbs;
private int alignment;
private int width;
private int height;
public GradientImage(int width, int height, Color[] colors, int alignment){
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
this.alignment = alignment;
this.width = width;
this.height = height;
this.colors = colors;
rgbs = new int[colors.length];
for (int i=0;i<rgbs.length;i++){
rgbs[i] = colors[i].getRGB();
}
try{
renderImage();
}catch(Exception error){error.printStackTrace();}
}
public GradientImage(int width, int height, Color[] colors, int[] positions, int alignment){
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
this.alignment = alignment;
this.width = width;
this.height = height;
this.colors = colors;
this.positions = positions;
rgbs = new int[colors.length];
for (int i=0;i<rgbs.length;i++){
rgbs[i] = colors[i].getRGB();
}
try{
renderImage();
}catch(Exception error){error.printStackTrace();}
}
public BufferedImage getImage(){
return image;
}
public BufferedImage getImageAsCircle(){
if (circleImage==null){
circleImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
circlePixels = ((DataBufferInt) circleImage.getRaster().getDataBuffer()).getData();
int radius = Math.min(width, height)>>1;
for (int x=0;x<width;x++){
for (int y=0;y<height;y++){
if (Math.sqrt((Math.max(width>>1, x)-Math.min(width>>1, x))*(Math.max(width>>1, x)-Math.min(width>>1, x))+(Math.max(height>>1, y)-Math.min(height>>1, y))*(Math.max(height>>1, y)-Math.min(height>>1, y)))<=radius){
circlePixels[x+y*width] = pixels[x+y*width];
}
}
}
}
return circleImage;
}
private void renderImage() throws Exception{
if (alignment==LINEAR_LEFT_TO_RIGHT){
int[] rgbRange = loadRGBRange(width, rgbs, positions);
for (int x=0;x<width;x++){
for (int y=0;y<height;y++){
pixels[x+y*width] = rgbRange[x];
}
}
}else if (alignment==LINEAR_RIGHT_TO_LEFT){
int[] rgbRange = loadRGBRange(width, rgbs, positions);
for (int x=0;x<width;x++){
for (int y=0;y<height;y++){
pixels[x+y*width] = rgbRange[width-x-1];
}
}
}else if (alignment==LINEAR_BOTTOM_TO_TOP){
int[] rgbRange = loadRGBRange(height, rgbs, positions);
for (int y=0;y<height;y++){
for (int x=0;x<width;x++){
pixels[x+y*width] = rgbRange[height-y-1];
}
}
}else if (alignment==LINEAR_TOP_TO_BOTTOM){
int[] rgbRange = loadRGBRange(height, rgbs, positions);
for (int y=0;y<height;y++){
for (int x=0;x<width;x++){
pixels[x+y*width] = rgbRange[y];
}
}
}else if (alignment==RADIAL_FROM_TOP_LEFT_CORNER){
int[] rgbRange = loadRGBRange((int) Math.sqrt((width-1)*(width-1)+(height-1)*(height-1)), rgbs, positions);
for (int x=0;x<width;x++){
for (int y=0;y<height;y++){
pixels[x+y*width] = rgbRange[(int) Math.sqrt((x-1)*(x-1)+(y-1)*(y-1))];
}
}
}else if (alignment==RADIAL_FROM_BOTTOM_LEFT_CORNER){
int[] rgbRange = loadRGBRange((int) Math.sqrt((width-1)*(width-1)+(height-1)*(height-1)), rgbs, positions);
for (int x=0;x<width;x++){
for (int y=0;y<height;y++){
pixels[x+(height-y-1)*width] = rgbRange[(int) Math.sqrt((x-1)*(x-1)+(y-1)*(y-1))];
}
}
}else if (alignment==RADIAL_FROM_TOP_RIGHT_CORNER){
int[] rgbRange = loadRGBRange((int) Math.sqrt((width-1)*(width-1)+(height-1)*(height-1)), rgbs, positions);
for (int x=0;x<width;x++){
for (int y=0;y<height;y++){
pixels[(width-x-1)+y*width] = rgbRange[(int) Math.sqrt((x-1)*(x-1)+(y-1)*(y-1))];
}
}
}else if (alignment==RADIAL_FROM_BOTTOM_RIGHT_CORNER){
int[] rgbRange = loadRGBRange((int) Math.sqrt((width-1)*(width-1)+(height-1)*(height-1)), rgbs, positions);
for (int x=0;x<width;x++){
for (int y=0;y<height;y++){
pixels[(width-x-1)+(height-y-1)*width] = rgbRange[(int) Math.sqrt((x-1)*(x-1)+(y-1)*(y-1))];
}
}
}else if (alignment==RADIAL_FROM_CENTER){
int[] divArray = divideArray(positions, 2);
BufferedImage quad1 = new GradientImage(width>>1, height>>1, colors, divArray, GradientImage.RADIAL_FROM_BOTTOM_RIGHT_CORNER).getImage();
BufferedImage quad2 = new GradientImage(width>>1, height>>1, colors, divArray, GradientImage.RADIAL_FROM_BOTTOM_LEFT_CORNER).getImage();
BufferedImage quad3 = new GradientImage(width>>1, height>>1, colors, divArray, GradientImage.RADIAL_FROM_TOP_RIGHT_CORNER).getImage();
BufferedImage quad4 = new GradientImage(width>>1, height>>1, colors, divArray, GradientImage.RADIAL_FROM_TOP_LEFT_CORNER).getImage();
Graphics2D g = image.createGraphics();
g.drawImage(quad1, 0, 0, null);
g.drawImage(quad2, width>>1, 0, null);
g.drawImage(quad3, 0, height>>1, null);
g.drawImage(quad4, width>>1, height>>1, null);
g.dispose();
}else if (alignment==RADIAL_FROM_CORNERS){
int[] divArray = divideArray(positions, 2);
BufferedImage quad1 = new GradientImage(width>>1, height>>1, colors, divArray, GradientImage.RADIAL_FROM_TOP_LEFT_CORNER).getImage();
BufferedImage quad2 = new GradientImage(width>>1, height>>1, colors, divArray, GradientImage.RADIAL_FROM_TOP_RIGHT_CORNER).getImage();
BufferedImage quad3 = new GradientImage(width>>1, height>>1, colors, divArray, GradientImage.RADIAL_FROM_BOTTOM_LEFT_CORNER).getImage();
BufferedImage quad4 = new GradientImage(width>>1, height>>1, colors, divArray, GradientImage.RADIAL_FROM_BOTTOM_RIGHT_CORNER).getImage();
Graphics2D g = image.createGraphics();
g.drawImage(quad1, 0, 0, null);
g.drawImage(quad2, width>>1, 0, null);
g.drawImage(quad3, 0, height>>1, null);
g.drawImage(quad4, width>>1, height>>1, null);
g.dispose();
}else if (alignment==LINEAR_DIAGONAL_UP){
int[] rgbRange = loadRGBRange((int) Math.sqrt((width-1)*(width-1)+(height-1)*(height-1)), rgbs, positions);
for (int x=0;x<width;x++){
for (int y=0;y<height;y++){
pixels[x+(height-y-1)*width] = rgbRange[Math.max(y-x, x-y)];
}
}
}else if (alignment==LINEAR_DIAGONAL_DOWN){
int[] rgbRange = loadRGBRange((int) Math.sqrt((width-1)*(width-1)+(height-1)*(height-1)), rgbs, positions);
for (int x=0;x<width;x++){
for (int y=0;y<height;y++){
pixels[x+y*width] = rgbRange[Math.max(y-x, x-y)];
}
}
}else if (alignment==LINEAR_FROM_TOP_RIGHT_CORNER){
int[] rgbRange = loadRGBRange((width+height)>>1, rgbs, positions);
for (int x=0;x<width;x++){
for (int y=0;y<height;y++){
pixels[x+(height-y-1)*width] = rgbRange[rgbRange.length-((x+y)>>1)-1];
}
}
}else if (alignment==LINEAR_FROM_TOP_LEFT_CORNER){
int[] rgbRange = loadRGBRange((width+height)>>1, rgbs, positions);
for (int x=0;x<width;x++){
for (int y=0;y<height;y++){
pixels[(width-x-1)+(height-y-1)*width] = rgbRange[rgbRange.length-((x+y)>>1)-1];
}
}
}else if (alignment==LINEAR_FROM_BOTTOM_RIGHT_CORNER){
int[] rgbRange = loadRGBRange((width+height)>>1, rgbs, positions);
for (int x=0;x<width;x++){
for (int y=0;y<height;y++){
pixels[x+y*width] = rgbRange[rgbRange.length-((x+y)>>1)-1];
}
}
}else if (alignment==LINEAR_FROM_BOTTOM_LEFT_CORNER){
int[] rgbRange = loadRGBRange((width+height)>>1, rgbs, positions);
for (int x=0;x<width;x++){
for (int y=0;y<height;y++){
pixels[(width-x-1)+y*width] = rgbRange[rgbRange.length-((x+y)>>1)-1];
}
}
}else if (alignment==LINEAR_FROM_CENTER){
int[] divArray = divideArray(positions, 2);
BufferedImage quad1 = new GradientImage(width>>1, height>>1, colors, divArray, GradientImage.LINEAR_FROM_BOTTOM_RIGHT_CORNER).getImage();
BufferedImage quad2 = new GradientImage(width>>1, height>>1, colors, divArray, GradientImage.LINEAR_FROM_BOTTOM_LEFT_CORNER).getImage();
BufferedImage quad3 = new GradientImage(width>>1, height>>1, colors, divArray, GradientImage.LINEAR_FROM_TOP_RIGHT_CORNER).getImage();
BufferedImage quad4 = new GradientImage(width>>1, height>>1, colors, divArray, GradientImage.LINEAR_FROM_TOP_LEFT_CORNER).getImage();
Graphics2D g = image.createGraphics();
g.drawImage(quad1, 0, 0, null);
g.drawImage(quad2, width>>1, 0, null);
g.drawImage(quad3, 0, height>>1, null);
g.drawImage(quad4, width>>1, height>>1, null);
g.dispose();
}else if (alignment==LINEAR_FROM_CORNERS){
int[] divArray = divideArray(positions, 2);
BufferedImage quad1 = new GradientImage(width>>1, height>>1, colors, divArray, GradientImage.LINEAR_FROM_TOP_LEFT_CORNER).getImage();
BufferedImage quad2 = new GradientImage(width>>1, height>>1, colors, divArray, GradientImage.LINEAR_FROM_TOP_RIGHT_CORNER).getImage();
BufferedImage quad3 = new GradientImage(width>>1, height>>1, colors, divArray, GradientImage.LINEAR_FROM_BOTTOM_LEFT_CORNER).getImage();
BufferedImage quad4 = new GradientImage(width>>1, height>>1, colors, divArray, GradientImage.LINEAR_FROM_BOTTOM_RIGHT_CORNER).getImage();
Graphics2D g = image.createGraphics();
g.drawImage(quad1, 0, 0, null);
g.drawImage(quad2, width>>1, 0, null);
g.drawImage(quad3, 0, height>>1, null);
g.drawImage(quad4, width>>1, height>>1, null);
g.dispose();
}else if (alignment==PATH_FROM_TOP_LEFT_CORNER){
int[] rgbRange = loadRGBRange(Math.max(width, height), rgbs, positions);
for (int x=0;x<width;x++){
for (int y=0;y<height;y++){
pixels[x+y*width] = rgbRange[Math.max(x, y)];
}
}
}else if (alignment==PATH_FROM_TOP_RIGHT_CORNER){
int[] rgbRange = loadRGBRange(Math.max(width, height), rgbs, positions);
for (int x=0;x<width;x++){
for (int y=0;y<height;y++){
pixels[(width-x-1)+y*width] = rgbRange[Math.max(x, y)];
}
}
}else if (alignment==PATH_FROM_BOTTOM_LEFT_CORNER){
int[] rgbRange = loadRGBRange(Math.max(width, height), rgbs, positions);
for (int x=0;x<width;x++){
for (int y=0;y<height;y++){
pixels[x+(height-y-1)*width] = rgbRange[Math.max(x, y)];
}
}
}else if (alignment==PATH_FROM_BOTTOM_RIGHT_CORNER){
int[] rgbRange = loadRGBRange(Math.max(width, height), rgbs, positions);
for (int x=0;x<width;x++){
for (int y=0;y<height;y++){
pixels[(width-x-1)+(height-y-1)*width] = rgbRange[Math.max(x, y)];
}
}
}else if (alignment==PATH_FROM_CENTER){
int[] divArray = divideArray(positions, 2);
BufferedImage quad1 = new GradientImage(width>>1, height>>1, colors, divArray, GradientImage.PATH_FROM_BOTTOM_RIGHT_CORNER).getImage();
BufferedImage quad2 = new GradientImage(width>>1, height>>1, colors, divArray, GradientImage.PATH_FROM_BOTTOM_LEFT_CORNER).getImage();
BufferedImage quad3 = new GradientImage(width>>1, height>>1, colors, divArray, GradientImage.PATH_FROM_TOP_RIGHT_CORNER).getImage();
BufferedImage quad4 = new GradientImage(width>>1, height>>1, colors, divArray, GradientImage.PATH_FROM_TOP_LEFT_CORNER).getImage();
Graphics2D g = image.createGraphics();
g.drawImage(quad1, 0, 0, null);
g.drawImage(quad2, width>>1, 0, null);
g.drawImage(quad3, 0, height>>1, null);
g.drawImage(quad4, width>>1, height>>1, null);
g.dispose();
}else if (alignment==PATH_FROM_CORNERS){
int[] divArray = divideArray(positions, 2);
BufferedImage quad1 = new GradientImage(width>>1, height>>1, colors, divArray, GradientImage.PATH_FROM_TOP_LEFT_CORNER).getImage();
BufferedImage quad2 = new GradientImage(width>>1, height>>1, colors, divArray, GradientImage.PATH_FROM_TOP_RIGHT_CORNER).getImage();
BufferedImage quad3 = new GradientImage(width>>1, height>>1, colors, divArray, GradientImage.PATH_FROM_BOTTOM_LEFT_CORNER).getImage();
BufferedImage quad4 = new GradientImage(width>>1, height>>1, colors, divArray, GradientImage.PATH_FROM_BOTTOM_RIGHT_CORNER).getImage();
Graphics2D g = image.createGraphics();
g.drawImage(quad1, 0, 0, null);
g.drawImage(quad2, width>>1, 0, null);
g.drawImage(quad3, 0, height>>1, null);
g.drawImage(quad4, width>>1, height>>1, null);
g.dispose();
}
}
public int[] divideArray(int[] array, int div){
if (array==null){
return null;
}
int[] arr = new int[array.length];
if (div==2){
for (int i=0;i<arr.length;i++){
arr[i] = array[i]>>1;
}
}else{
for (int i=0;i<arr.length;i++){
arr[i] = array[i]/div;
}
}
return arr;
}
public int[] loadRGBRange(int length, int[] rgbs) throws Exception {
if (rgbs==null){
throw new Exception("RGB[]'s cannot be null");
}
if (length==0){
throw new Exception("Length cannot be 0");
}
if (rgbs.length==0){
throw new Exception("RGB[]'s length cannot be 0");
}
int[] rgbRange = new int[length];
if (rgbs.length==1){
for (int i=0;i<rgbRange.length;i++){
rgbRange[i] = rgbs[0];
}
return rgbRange;
}
int[] positions = new int[rgbs.length];
double pos = 0;
double block = (double) length/(rgbs.length-1);
for (int i=0;i<positions.length;i++){
positions[i] = (int) pos;
pos+=block;
}
int[] as = new int[rgbs.length];
int[] rs = new int[rgbs.length];
int[] gs = new int[rgbs.length];
int[] bs = new int[rgbs.length];
for (int i=0;i<rgbs.length;i++){
as[i] = (rgbs[i]>>24) & 0xff;
rs[i] = (rgbs[i]>>16) & 0xff;
gs[i] = (rgbs[i]>>8) & 0xff;
bs[i] = (rgbs[i]) & 0xff;
}
int[] adifs = new int[rgbs.length-1];
int[] rdifs = new int[rgbs.length-1];
int[] gdifs = new int[rgbs.length-1];
int[] bdifs = new int[rgbs.length-1];
for (int i=0;i<rgbs.length-1;i++){
adifs[i] = as[i]-as[i+1];
rdifs[i] = rs[i]-rs[i+1];
gdifs[i] = gs[i]-gs[i+1];
bdifs[i] = bs[i]-bs[i+1];
}
double[] ab = new double[rgbs.length-1];
double[] rb = new double[rgbs.length-1];
double[] gb = new double[rgbs.length-1];
double[] bb = new double[rgbs.length-1];
for (int i=0;i<rgbs.length-1;i++){
int l = positions[i+1]-positions[i];
ab[i] = (double) adifs[i]/l;
rb[i] = (double) rdifs[i]/l;
gb[i] = (double) gdifs[i]/l;
bb[i] = (double) bdifs[i]/l;
}
double a = as[0];
double r = rs[0];
double g = gs[0];
double b = bs[0];
int color = 0;
for (int i=0;i<rgbRange.length;i++){
rgbRange[i] = ((int)a<<24)|((int)r<<16)|((int)g<<8)|((int)b);
if (i+1>positions[0] && i+1<positions[positions.length-1]){
if (i==positions[color+1]){
color++;
a = as[color];
r = rs[color];
g = gs[color];
b = bs[color];
}else{
a-=ab[color];
r-=rb[color];
g-=gb[color];
b-=bb[color];
}
}
}
return rgbRange;
}
public int[] loadRGBRange(int length, int[] rgbs, int[] positions) throws Exception {
if (positions==null){
return loadRGBRange(length, rgbs);
}
if (rgbs==null){
throw new Exception("RGB[]'s cannot be null");
}
if (length==0){
throw new Exception("Length cannot be 0");
}
if (rgbs.length==0 || positions.length==0){
return null;
}
if (positions.length!=rgbs.length){
throw new Exception("The length of Positions[] must equals the length of RGB[]'s");
}
for (int i=0;i<positions.length;i++){
if (positions[i]>length){
throw new Exception("Any positions cannot be greater than the length");
}
}
int[] rgbRange = new int[length];
if (rgbs.length==1){
for (int i=0;i<rgbRange.length;i++){
rgbRange[i] = rgbs[0];
}
return rgbRange;
}
int[] as = new int[rgbs.length];
int[] rs = new int[rgbs.length];
int[] gs = new int[rgbs.length];
int[] bs = new int[rgbs.length];
for (int i=0;i<rgbs.length;i++){
as[i] = (rgbs[i]>>24) & 0xff;
rs[i] = (rgbs[i]>>16) & 0xff;
gs[i] = (rgbs[i]>>8) & 0xff;
bs[i] = (rgbs[i]) & 0xff;
}
int[] adifs = new int[rgbs.length-1];
int[] rdifs = new int[rgbs.length-1];
int[] gdifs = new int[rgbs.length-1];
int[] bdifs = new int[rgbs.length-1];
for (int i=0;i<rgbs.length-1;i++){
adifs[i] = as[i]-as[i+1];
rdifs[i] = rs[i]-rs[i+1];
gdifs[i] = gs[i]-gs[i+1];
bdifs[i] = bs[i]-bs[i+1];
}
double[] ab = new double[rgbs.length-1];
double[] rb = new double[rgbs.length-1];
double[] gb = new double[rgbs.length-1];
double[] bb = new double[rgbs.length-1];
for (int i=0;i<rgbs.length-1;i++){
int l = positions[i+1]-positions[i];
ab[i] = (double) adifs[i]/l;
rb[i] = (double) rdifs[i]/l;
gb[i] = (double) gdifs[i]/l;
bb[i] = (double) bdifs[i]/l;
}
double a = as[0];
double r = rs[0];
double g = gs[0];
double b = bs[0];
int color = 0;
for (int i=0;i<rgbRange.length;i++){
rgbRange[i] = ((int)a<<24)|((int)r<<16)|((int)g<<8)|((int)b);
if (i+1>positions[0] && i+1<positions[positions.length-1]){
if (i==positions[color+1]){
color++;
a = as[color];
r = rs[color];
g = gs[color];
b = bs[color];
}else{
a-=ab[color];
r-=rb[color];
g-=gb[color];
b-=bb[color];
}
}
}
return rgbRange;
}
}
答案 1 :(得分:0)
我使用http://real-me.net/ddyer/java/imagedemo/imagedemo.java处的方法 将任意透明度应用于相应的jpg图像。对不起,那里 曾经是一个演示小程序,但是oracle在他们的安全狂热中使用了它。您 可以在http://boardspace.net/
的所有游戏中查看实际操作方法