java 图片数字图像处理之图片缩小

package test;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

/**
 * 因为等距采样法放大或者缩小的图像素点比较低,所以采取局部俊值法
 * 根据上一张的内容讲到,将原来的图形像素填充到更大的区域里面去,分到大的空间,但是采取的像素是每个区域的开头的那个点,而这里是采取
 * 区域内每一个点的均值作为缩小的那个图的像素点值
 * @author Administrator
 *
 */
public class ImageChangeTwo extends ImageChange {

	public ImageChangeTwo(String filePath, String newFilePath)
			throws IOException {
		super(filePath, newFilePath);
		// TODO 自动生成的构造函数存根
	}
	/**
	 * @param width 缩小后图片的宽
	 * @param height 缩小后图片的高
	 */
	public void flex(float width, float height) throws IOException {
		// TODO 自动生成的方法存根
		float  kx  = this.getOldBufferedImage().getWidth()/width;//算出旧图比新图宽度的比例
		float ky = this.getOldBufferedImage().getHeight()/height;//算出旧图比新图高度的比例
		System.out.println("kx:"+kx);
		System.out.println("ky:"+ky);
		if(kx>1||ky>1){
			doBeSmall(width,height);
		}else{
			doBeBig(width,height);
		}
	}
	

	private void doBeBig(float width, float height) {
		// TODO 自动生成的方法存根
		//采用双立方插值算法 或双线性插值放大
	}
	/**
	 * 采用局部均值法进行缩小
	 * @param width
	 * @param height
	 */
	private void doBeSmall(float width, float height) throws IOException {
		// TODO 自动生成的方法存根
		float  kx  = this.getOldBufferedImage().getWidth()/width;//算出旧图比新图宽度的比例
		float ky = this.getOldBufferedImage().getHeight()/height;//算出旧图比新图高度的比例
		int oldOffset=0,startX=0,startY=0;
		int oldScansize=this.getOldBufferedImage().getWidth();
		int oldWidth = this.getOldBufferedImage().getWidth();
		int oldHeight = this.getOldBufferedImage().getHeight();
		//定义旧图片像素数组
		int[] pix = new int[oldOffset+(oldHeight-startY)*oldScansize+(oldWidth-startX)];
		this.getOldBufferedImage().getRGB(startX, startY, oldWidth, oldHeight, pix, oldOffset, oldScansize);
		//默认offset,startX,startY为0,scansize=newWidth
		int[] newPix = new int [(int)(0+(height-0)*width+(width-0))] ;
		//老规矩 遍历
		for(int y =0; y<height;y++){
			for(int x =0;x<width;x++){
				//现在取到的是一个矩形的像素然后再用一个循环进去里面把像素的RGB像素值都取出来
				int r=0,g=0,b=0;
				ColorModel cm = ColorModel.getRGBdefault();
				/*
				 * 返回描述整数 RGB 值的默认格式的 DirectColorModel,颜色空间为默认的 ColorSpace(即 sRGB)。
				 * RGB 值的格式是一个 8 位的整数,从最高有效字节到最低有效字节的相应顺序排列 alpha、红色、绿色和蓝色颜色分量,格式如下:0xAARRGGBB。颜色分量未与 alpha 分量预乘。
				 * 此格式不一定表示特定设备或所有图像的本机或最有效的 ColorModel。它只是一种通用的颜色模型格式。 
				 */
				System.out.println(ky);
				System.out.println(kx);
				System.out.println((int)ky);
				System.out.println((int)kx);
				for(int my=0;my<(int)ky;my++){//这里记住要把ky转为int类型,不然会有错误,因为如果不强转的话,那么因为是float的原因,my将会自动读取到多一位,就相当于是my<=ky,这样会读到别的区域中的数值去
					for(int mx = 0;mx<(int)kx;mx++){//这里记得要把kx转为int类型,不然会有错误
						r=r+cm.getRed(pix [ (int)(y*ky+my)*oldWidth+(int)(x*kx+mx)]);
						g=g+cm.getGreen(pix[((int)(y*ky+my))*oldScansize+(int)(x*kx+mx)]);
						b=b+cm.getBlue(pix[((int)(y*ky+my))*oldScansize+(int)(x*kx+mx)]);
					}
				}
				
				//求均值
				r=r/((int)(kx*ky));
				g=g/((int)(kx*ky));
				b=b/((int)(kx*ky));
				
				newPix[(int)(y*width)+x]=255<<24 | r<<16 | g<<8 | b;
				 //255<<24 | r<<16 | g<<8 | b  这个公式解释一下,颜色的RGB在内存中是  
                //以二进制的形式保存的,从右到左1-8位表示blue,9-16表示green,17-24表示red  
                //所以"<<24" "<<16" "<<8"分别表示左移24,16,8位
				
			}
		}
		BufferedImage imgOut = new BufferedImage((int)width, (int)height, this.getOldBufferedImage().getType());  
        
        imgOut.setRGB(0, 0, (int)width, (int)height, newPix, 0, (int) width);     
        
        ImageIO.write(imgOut, "jpg", new File(this.getNewFilePath()));
        System.out.println(new File(this.getNewFilePath()).exists());
	}
	
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值