سؤال

كيف أقوم بتغيير قيمة ألفا العالمية لـ BufferedImage في Java؟(أي.اجعل كل بكسل في الصورة له قيمة ألفا 100 له قيمة ألفا 80)

هل كانت مفيدة؟

المحلول

لا أعتقد أن هناك أمرًا بسيطًا واحدًا للقيام بذلك.بعض الخيارات:

الأول هو الأسهل في التنفيذ، IMO.

نصائح أخرى

وNeil كوفي: شكرا، لقد كانت تبحث عن هذا أيضا. ومع ذلك، لم التعليمة البرمجية الخاصة بك لا يعمل بشكل جيد للغاية بالنسبة لي (وأصبحت خلفية بيضاء سوداء).

وأنا مشفرة شيئا من هذا القبيل، وأنها تعمل تماما:

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 ((بايت) 125)؛ مجموعة ألفا الآن 0-255.

والأمل هناك من يرى أن هذا مفيد.

هذا سؤال قديم، لذا فأنا لا أجيب عليه من أجل البروتوكول الاختياري، ولكن لأولئك مثلي الذين يجدون هذا السؤال لاحقًا.

ألفا كومبوزيت

كما ذكر المخطط التفصيلي الممتاز لـ @Michael، يمكن لعملية AlphaComposite تعديل قناة ألفا.ولكن فقط بطرق معينة، والتي يصعب علي فهمها إلى حد ما:

enter image description here

يكون الصيغة لمعرفة كيفية تأثير عملية "النهاية" على قناة ألفا.علاوة على ذلك، يؤثر هذا على قنوات RGB أيضًا، لذلك إذا كانت لديك بيانات ألوان تحتاج إلى عدم التغيير، فإن AlphaComposite ليس هو الحل.

BufferedImageOps

LookupOp

هناك عدة أنواع من BufferedImageOp (انظر 4.10.6 هنا).في الحالة الأكثر عمومية، يمكن تحقيق مهمة OP بواسطة أ LookupOp, ، الأمر الذي يتطلب بناء صفائف البحث.لتعديل قناة ألفا فقط، قم بتوفير مصفوفة هوية (مصفوفة حيث table[i] = i) لقنوات RGB، ومصفوفة منفصلة لقناة ألفا.قم بملء المصفوفة الأخيرة بـ table[i] = f(i), ، أين f() هي الوظيفة التي تريد التعيين من خلالها من قيمة ألفا القديمة إلى قيمة ألفا الجديدة.على سبيل المثالإذا كنت تريد "جعل كل بكسل في الصورة له قيمة ألفا 100 له قيمة ألفا 80"، قم بتعيين table[100] = 80.(النطاق الكامل هو من 0 إلى 255.) انظر كيفية زيادة العتامة في طمس غاوسي للحصول على نموذج التعليمات البرمجية.

RescaleOp

ولكن بالنسبة لمجموعة فرعية من هذه الحالات، هناك طريقة أبسط للقيام بذلك، ولا تتطلب إعداد جدول بحث.لو f() هي دالة خطية بسيطة، استخدم a RescaleOp.على سبيل المثال، إذا كنت تريد تعيين newAlpha = oldAlpha - 20, ، استخدم RescaleOp مع عامل مقياس 1 وإزاحة -20.إذا كنت تريد تعيين newAlpha = oldAlpha * 0.8, ، استخدم مقياس مقياس 0.8 وإزاحة 0.في كلتا الحالتين، عليك مرة أخرى توفير عوامل مقياس وهمية وإزاحات لقنوات RGB:

new RescaleOp({1.0f, 1.0f, 1.0f, /* alpha scaleFactor */ 0.8f},
              {0f, 0f, 0f, /* alpha offset */ -20f}, null)

انظر مرة أخرى 4.10.6 هنا بالنسبة لبعض الأمثلة التي توضح المبادئ بشكل جيد، ولكنها ليست خاصة بقناة ألفا.

كلاهما RescaleOp و LookupOp السماح بتعديل BufferedImage في مكانه.

ولأجمل تبحث تأثير تغير ألفا، يمكنك استخدام التغير النسبي ألفا لكل بكسل (بدلا من مجموعة ثابتة، أو لقطة الخطية)

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);            
        }
    }
}

وأنا متأكد 99٪ الأساليب التي تدعي للتعامل مع قيمة "RGB" معبأة في كثافة التعامل مع الواقع ARGB. لذلك يجب عليك أن تكون قادرة على فعل شيء مثل:

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; }

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top