완충학의 알파 값을 변경 하시겠습니까?
-
20-08-2019 - |
문제
Java에서 BufferedImage의 글로벌 알파 값을 어떻게 변경합니까? (즉, 알파 값이 100 인 이미지의 모든 픽셀을 알파 값은 80입니다)
해결책
나는 이것을하는 단순한 간단한 명령이 있다고 생각하지 않습니다. 몇 가지 옵션 :
- An과 함께 다른 이미지로 복사하십시오 알파 컴포이트 지정된 (단점 : 제자리에 변환되지 않음)
- 직접 조작하십시오 래스터 (단점 : 이어질 수 있습니다 관리되지 않은 이미지)
- 필터를 사용하거나 사용하십시오 BufferedImageop
첫 번째는 IMO를 구현하기가 가장 간단합니다.
다른 팁
@Neil Coffey : 감사합니다. 저도 이것도 찾고있었습니다. 그러나 귀하의 코드는 나에게 잘 작동하지 않았습니다 (흰색 배경은 검은 색이되었습니다).
나는 이와 같은 것을 코딩했고 완벽하게 작동합니다.
public void setAlpha(byte alpha) {
alpha %= 0xff;
for (int cx=0;cx<obj_img.getWidth();cx++) {
for (int cy=0;cy<obj_img.getHeight();cy++) {
int color = obj_img.getRGB(cx, cy);
int mc = (alpha << 24) | 0x00ffffff;
int newcolor = color & mc;
obj_img.setRGB(cx, cy, newcolor);
}
}
}
여기서 obj_img는 bufferedimage.type_int_argb입니다.
나는 setalpha ((byte) 125)로 알파를 바꿉니다. 알파 범위는 이제 0-255입니다.
누군가가 이것이 유용하다는 것을 알기를 바랍니다.
이것은 오래된 질문이므로, 나는 OP를 위해 대답하지 않고 나중에이 질문을 찾는 나와 같은 사람들에게 대답하지 않습니다.
알파 컴포이트
@Michael의 우수한 개요가 언급했듯이, 알파 컴포지 사이트 작업은 알파 채널을 수정할 수 있습니다. 그러나 어떤면에서만, 나에게 이해하기가 다소 어렵다.
~이다 공식 "오버"작업이 알파 채널에 영향을 미치는 방식. 또한 이것은 RGB 채널에도 영향을 미치므로 변하지 않아야 할 색상 데이터가 있으면 알파계가 답이 아닙니다.
BufferedImageOps
조회
BufferedImageop의 여러 종류가 있습니다 (참조 4.10.6 여기). 보다 일반적인 경우 OP의 임무는 조회, 조회 어레이를 구축해야합니다. 알파 채널 만 수정하려면 RGB 채널의 아이덴티티 어레이 (테이블 [i] = i)와 알파 채널의 별도 배열을 공급하십시오. 후자의 배열을 채우십시오 table[i] = f(i)
, 어디 f()
오래된 알파 값에서 새로 매핑하려는 기능입니다. 예 : "알파 값이 100 인 이미지에서 모든 픽셀을 만들고 싶다면 알파 값이 80입니다", table[100] = 80
. (전체 범위는 0 ~ 255입니다.) 가우스 블러에서 불투명도를 높이는 방법 코드 샘플의 경우.
rescaleop
그러나 이러한 경우의 하위 집합의 경우 더 간단한 방법이있어 조회 테이블을 설정할 필요가 없습니다. 만약에 f()
단순하고 선형 함수이며 사용하십시오 rescaleop. 예를 들어, 설정하려는 경우 newAlpha = oldAlpha - 20
, ScaleFactor가 1이고 -20의 오프셋이있는 rescaleop을 사용하십시오. 설정하려면 newAlpha = oldAlpha * 0.8
, 0.8의 ScaleFactor와 0의 오프셋을 사용하십시오. 어느 경우 모두, 당신은 다시 RGB 채널에 더미 ScaleFactors와 오프셋을 제공해야합니다.
new RescaleOp({1.0f, 1.0f, 1.0f, /* alpha scaleFactor */ 0.8f},
{0f, 0f, 0f, /* alpha offset */ -20f}, null)
다시 참조하십시오 4.10.6 여기 원리를 잘 보여주는 일부 예제의 경우, 알파 채널에만 국한되지는 않습니다.
더 잘 보이는 알파 변화 효과의 경우 픽셀 당 상대 알파 변경을 사용할 수 있습니다 (정적 세트 대신 또는 클리핑 선형)
public static void modAlpha(BufferedImage modMe, double modAmount) {
//
for (int x = 0; x < modMe.getWidth(); x++) {
for (int y = 0; y < modMe.getHeight(); y++) {
//
int argb = modMe.getRGB(x, y); //always returns TYPE_INT_ARGB
int alpha = (argb >> 24) & 0xff; //isolate alpha
alpha *= modAmount; //similar distortion to tape saturation (has scrunching effect, eliminates clipping)
alpha &= 0xff; //keeps alpha in 0-255 range
argb &= 0x00ffffff; //remove old alpha info
argb |= (alpha << 24); //add new alpha info
modMe.setRGB(x, y, argb);
}
}
}
나는 실제로 ArgB와 관련된 Int에 포장 된 "RGB"값을 다루는 방법을 99% 확신합니다. 따라서 다음과 같은 작업을 수행 할 수 있어야합니다.
for (all x,y values of image) {
int argb = img.getRGB(x, y);
int oldAlpha = (argb >>> 24);
if (oldAlpha == 100) {
argb = (80 << 24) | (argb & 0xffffff);
img.setRGB(x, y, argb);
}
}
속도의 경우 방법을 사용하여 픽셀 값의 블록을 검색 할 수 있습니다.
먼저 BufferedImage를 유형 이미지에 복사해야 할 수도 있습니다. BufferedImage.TYPE_INT_ARGB
. 이미지가 유형 인 경우 BufferedImage.TYPE_INT_RGB
, 그런 다음 알파 구성 요소가 올바르게 설정되지 않습니다. BufferedImage가 유형 인 경우 BufferedImage.TYPE_INT_ARGB
, 아래 코드는 작동합니다.
/**
* Modifies each pixel of the BufferedImage so that the selected component (R, G, B, or A)
* is adjusted by delta. Note: the BufferedImage must be of type BufferedImage.TYPE_INT_ARGB.
* @param src BufferedImage of type BufferedImage.TYPE_INT_ARGB.
* @param colorIndex 0=red, 1=green, 2=blue, 3= alpha
* @param delta amount to change component
* @return
*/
public static BufferedImage adjustAColor(BufferedImage src,int colorIndex, int delta) {
int w = src.getWidth();
int h = src.getHeight();
assert(src.getType()==BufferedImage.TYPE_INT_ARGB);
for (int y = 0; y < h; y++)
for (int x = 0; x < w; x++) {
int rgb = src.getRGB(x,y);
java.awt.Color color= new java.awt.Color(rgb,true);
int red=color.getRed();
int green=color.getGreen();
int blue=color.getBlue();
int alpha=color.getAlpha();
switch (colorIndex) {
case 0: red=adjustColor(red,delta); break;
case 1: green=adjustColor(green,delta); break;
case 2: blue=adjustColor(blue,delta); break;
case 3: alpha=adjustColor(alpha,delta); break;
default: throw new IllegalStateException();
}
java.awt.Color adjustedColor=new java.awt.Color(red,green,blue,alpha);
src.setRGB(x,y,adjustedColor.getRGB());
int gottenColorInt=src.getRGB(x,y);
java.awt.Color gottenColor=new java.awt.Color(gottenColorInt,true);
assert(gottenColor.getRed()== red);
assert(gottenColor.getGreen()== green);
assert(gottenColor.getBlue()== blue);
assert(gottenColor.getAlpha()== alpha);
}
return src;
}
private static int adjustColor(int value255, int delta) {
value255+= delta;
if (value255<0) {
value255=0;
} else if (value255>255) {
value255=255;
}
return value255;
}