在Java中,将彩色图像逐渐随机更改为灰度?

在Java中,将彩色图像逐渐随机更改为灰度?,java,image,colors,grayscale,Java,Image,Colors,Grayscale,我做了一些研究并找到了一些线索,但我需要帮助确定将彩色图像转换为灰度的最佳方法。虽然有很多快速转换的例子,但我正在寻找一个渐进的和随机的转换。所以,我想显示一个图像,随着时间的推移,它会变成一个灰度图像,从图像表面的0-100%到随机像素 我不需要完整的代码,只需要一些方法,也许这会引导我走向正确的方向 我的一个想法是将不同灰度的图像进行交换。这是我能做的最好的了吗?没有实时转换?谢谢大家。这就是我所拥有的和它目前所做的 import java.io.File; import java.io.I

我做了一些研究并找到了一些线索,但我需要帮助确定将彩色图像转换为灰度的最佳方法。虽然有很多快速转换的例子,但我正在寻找一个渐进的和随机的转换。所以,我想显示一个图像,随着时间的推移,它会变成一个灰度图像,从图像表面的0-100%到随机像素

我不需要完整的代码,只需要一些方法,也许这会引导我走向正确的方向


我的一个想法是将不同灰度的图像进行交换。这是我能做的最好的了吗?没有实时转换?

谢谢大家。这就是我所拥有的和它目前所做的

import java.io.File;
import java.io.IOException;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.util.*;

public class Color2GrayscaleImage{
  public static void main(String args[])throws IOException{

    Scanner input= new Scanner(System.in);

    System.out.println("What percent of the image do you want grayscaled?");

    int percentCover=input.nextInt();
    double per=(percentCover/100);
    BufferedImage img = null;
    File f = null;

    try{
      f = new File("media/mini0n.jpg");
      img = ImageIO.read(f);
    }catch(IOException e){
      System.out.println(e);
    }

    //get image width and height
    int width = img.getWidth();
    int height = img.getHeight();

System.out.println(width+"x"+height+". "+width*height+ " total pixels.");

    //convert entire image to grayscale
    //for(int y = 0; y < height; y++){
      //for(int x = 0; x < width; x++){
        //int p = img.getRGB(x,y);
        int num;
        for (num=0; num<5; num++){
        //randomly select pixels to be converted to grayscale
      for(int heightY = 0; heightY < height*(1+per); heightY++){
      for(int widthX = 0; widthX < width*(1+per); widthX++){

    Random random=new Random();
    int x= random.nextInt((width));
      int y= random.nextInt((height));

        int p = img.getRGB(x,y);

        int a = (p>>24)&0xff;
        int r = (p>>16)&0xff;
        int g = (p>>8)&0xff;
        int b = p&0xff;

        //calculate average
        int avg = (r+g+b)/3;

        //replace RGB value with avg
        p = (a<<24) | (avg<<16) | (avg<<8) | avg;

        img.setRGB(x, y, p);

        }
   }
    //write image
    try{
      f = new File("media/altered/new_IMAGE"+num+".jpg");
      ImageIO.write(img, "jpg", f);
    }catch(IOException e){
      System.out.println(e);
    }}
   num++;
  }
}
导入java.io.File;
导入java.io.IOException;
导入java.awt.image.buffereImage;
导入javax.imageio.imageio;
导入java.util.*;
公共类Color2GrayscaleImage{
公共静态void main(字符串args[])引发IOException{
扫描仪输入=新扫描仪(System.in);
System.out.println(“您希望灰度化图像的百分比是多少?”);
int percentCover=input.nextInt();
每增加一倍=(覆盖率/100%);
BuffereImage img=null;
文件f=null;
试一试{
f=新文件(“media/mini0n.jpg”);
img=图像读取(f);
}捕获(IOE异常){
系统输出打印ln(e);
}
//获取图像宽度和高度
int width=img.getWidth();
int height=img.getHeight();
System.out.println(宽度+x+高度+宽度*高度+总像素);
//将整个图像转换为灰度
//对于(int y=0;y24)&0xff;
int r=(p>>16)和0xff;
int g=(p>>8)和0xff;
intb=p&0xff;
//计算平均数
国际平均值=(r+g+b)/3;
//用平均值替换RGB值

p=(a据我所知,这个想法是逐渐的灰度化;即逐渐收敛到灰度图像。这可以通过收敛到它来实现;收敛问题

如果数量大于收敛值,则减少;如果数量较小,则增加

在第一个循环中,我们找到平均值(收敛值)

int[]avg=newint[pix.length];
对于(i=0;i16,p2=(p&0x0000ff00)>>8,p3=p&0x000000ff;
平均值[i+j*wc]=(p1+p2+p3)/3;
}
在第二个循环中,我们执行收敛:

我们增加/减少三个颜色分量中的每一个,直到所有颜色分量都收敛:在这种情况下,您可以选择10的小步

如果该值在收敛的一个单位内(例如小于10),我们将该值设置为收敛值。如果所有像素都出现这种情况,我们将达到灰度

boolean f1=false, f2=false, f3=false;
while(true) {
    f1=false; f2=false; f3=false;
    for(i=0; i<wc; i++)
    for(j=0; j<hc; j++) {
      int p=bim.getRGB(i, j);
      int p1=(p&0x00ff0000)>>16, p2=(p&0x0000ff00)>>8, p3=p&0x000000ff;
      if(p1>avg[i+j*wc]+10) { p1-=10; if(p1<avg[i+j*wc]) p1=avg[i+j*wc]; f1=true; }
      else if(p1<avg[i+j*wc]-10) { p1+=10; if(p1>avg[i+j*wc]) p1=avg[i+j*wc]; f1=true; }
      if(p2>avg[i+j*wc]+10) { p2-=10; if(p2<avg[i+j*wc]) p2=avg[i+j*wc]; f2=true; }
      else if(p2<avg[i+j*wc]-10) { p2+=10; if(p2>avg[i+j*wc]) p2=avg[i+j*wc]; f2=true; }
      if(p3>avg[i+j*wc]+10) { p3-=10; if(p3<avg[i+j*wc]) p3=avg[i+j*wc]; f3=true; }
      else if(p3<avg[i+j*wc]-10) { p3+=10; if(p3>avg[i+j*wc]) p3=avg[i+j*wc]; f3=true; }
      bim.setRGB(i, j, 0xff000000|(p1<<16)|(p2<<8)|p3);
    }
    if(f1 || f2 || f3) ; else   {    System.err.println("no change"); break; }
}
boolean f1=false,f2=false,f3=false;
while(true){
f1=假;f2=假;f3=假;
对于(i=0;i16,p2=(p&0x0000ff00)>>8,p3=p&0x000000ff;

如果(p1>avg[i+j*wc]+10{p1-=10;如果(p1avg[i+j*wc]+10{p2-=10;如果(p2avg[i+j*wc]+10){p3-=10;如果(P3)你能说得更具体些吗?那么,你想知道如何选择一个以前没有选择过的随机像素,并将其更改为灰度?0%100%的所有像素都是按比例选择的?展示你的想法示例。使用gimp或photoshop等工具创建它们。感谢你的回答。因此,我希望图像逐渐改变from颜色从其表面的0%到100%的灰度,但选择随机像素(到灰度)每次从0到100%。希望这更清晰。我想不出任何解决方案不包括为每个像素保留进度值。抱歉,伙计们,这是图像。好的,图像显示了你想要的:这不是随机改变灰度像素-这是逐渐灰度化-这是如下效果visible@gpasch.好极了谢谢!这是我从你的帮助中得到的。我当然可以解决这个问题!@gpash。如果你没有看到我在下面对此的回应,我深表歉意,但谢谢你!这是我本不会考虑的事情,比我原来想的更适合我的需要。干杯!
boolean f1=false, f2=false, f3=false;
while(true) {
    f1=false; f2=false; f3=false;
    for(i=0; i<wc; i++)
    for(j=0; j<hc; j++) {
      int p=bim.getRGB(i, j);
      int p1=(p&0x00ff0000)>>16, p2=(p&0x0000ff00)>>8, p3=p&0x000000ff;
      if(p1>avg[i+j*wc]+10) { p1-=10; if(p1<avg[i+j*wc]) p1=avg[i+j*wc]; f1=true; }
      else if(p1<avg[i+j*wc]-10) { p1+=10; if(p1>avg[i+j*wc]) p1=avg[i+j*wc]; f1=true; }
      if(p2>avg[i+j*wc]+10) { p2-=10; if(p2<avg[i+j*wc]) p2=avg[i+j*wc]; f2=true; }
      else if(p2<avg[i+j*wc]-10) { p2+=10; if(p2>avg[i+j*wc]) p2=avg[i+j*wc]; f2=true; }
      if(p3>avg[i+j*wc]+10) { p3-=10; if(p3<avg[i+j*wc]) p3=avg[i+j*wc]; f3=true; }
      else if(p3<avg[i+j*wc]-10) { p3+=10; if(p3>avg[i+j*wc]) p3=avg[i+j*wc]; f3=true; }
      bim.setRGB(i, j, 0xff000000|(p1<<16)|(p2<<8)|p3);
    }
    if(f1 || f2 || f3) ; else   {    System.err.println("no change"); break; }
}