JAVA 图片缩小算法

该博客介绍了如何使用Java Swing构建一个简单的图片查看器,并实现了图片的双线性内插法缩放功能。通过读取BMP格式的图片文件,解析图像数据,然后使用自定义的`zoomdata_old_bilinear`方法进行缩放,最后在窗口中显示。代码包括了布局管理、文件读取、颜色处理和图形绘制等关键部分。
摘要由CSDN通过智能技术生成

  

package com.company;

import javax.swing.*;
import java.awt.*;
import java.io.BufferedInputStream;
import java.io.FileInputStream;

public class priUI extends JFrame
{
    public static void main(String[] args)
    {
        priUI ui = new priUI();
        ui.initUI();
    }

    public void initUI()
    {
        this.setSize(600, 920);
        this.setTitle("图片查看器");

        // 设置布局
        FlowLayout layout = new FlowLayout();
        this.setLayout(layout);

        JPanel center = new myPanel();
        center.setPreferredSize(new Dimension(400, 900));
        center.setBackground(Color.WHITE);
        this.add(center);

        this.setDefaultCloseOperation(3);
        this.setVisible(true);
    }

    public int[][] readFile(String path)
    {
        try
        {
            // 创建读取文件的字节流
            FileInputStream fileInputStream = new FileInputStream(path);
            BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
            // 读取时丢掉前面的18位,
            // 读取图片的18~21的宽度
            bufferedInputStream.skip(18);

            byte[] b = new byte[4];
            bufferedInputStream.read(b);
            int width_old = byte2Int(b);

            bufferedInputStream.read(b);
            int height_old = byte2Int(b);

            // 使用数组保存得图片的高度和宽度
            int[][] data_old = new int[height_old][width_old * 3];

            // 读取位图中的数据,位图中数据时从54位开始的,在读取数据前要丢掉前面的数据
            bufferedInputStream.skip(28);
            for (int i = 0; i < height_old; i++)
            {
                for (int j = 0; j < width_old; j++)
                {
                    // bmp的图片在window里面世3个byte为一个像素
                    int blue  = bufferedInputStream.read();
                    int green = bufferedInputStream.read();
                    int red   = bufferedInputStream.read();

                    data_old[i][3 * j]     = blue;
                    data_old[i][3 * j + 1] = green;
                    data_old[i][3 * j + 2] = red;
                }
            }
            return data_old;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }

    public double bilinear(double a, double b, int uv, int u1v, int uv1, int u1v1)
    {
        return (double) (uv * (1 - a) * (1 - b) + u1v * a * (1 - b) + uv1 * b * (1 - a) + u1v1 * a * b);
    }

    // https://blog.csdn.net/tofro/article/details/7169674
    public void zoomdata_old_bilinear( int[][] pdst, int dw, int dh, int[][] psrc, int sw, int sh )
    {
        int  i, j;

        for ( i = 0; i < dh; i++ )
        {
            for ( j = 0; j < dw; j++ )
            {
                int    ii, jj;
                double    u, v, r, g, b;
                v    = (i * sh) / (double) (dh);
                u    = (j * sw) / (double) (dw);
                ii    = (int) (v);
                jj    = (int) (u);

                b = bilinear( u - jj, v - ii,
                            psrc[ii][jj * 3],
                            psrc[ii][(jj + 1) * 3],
                            psrc[(ii + 1)][(jj + 1) * 3],
                            psrc[(ii + 1)][(jj) * 3]);

                g = bilinear( u - jj, v - ii,
                            psrc[ii][jj * 3 + 1],
                            psrc[ii][(jj + 1) * 3 + 1],
                            psrc[(ii + 1)][(jj + 1) * 3 + 1],
                            psrc[(ii + 1)][(jj) * 3] + 1);

                r = bilinear( u - jj, v - ii,
                            psrc[ii][jj * 3 + 2],
                            psrc[ii][(jj + 1) * 3 + 2],
                            psrc[(ii + 1)][(jj + 1) * 3 + 2],
                            psrc[(ii + 1)][(jj) * 3] + 2);

                pdst[i][j * 3 + 2]    = (int)r;
                pdst[i][j * 3 + 1]    = (int)g;
                pdst[i][j * 3]        = (int)b;
            }
        }
    }

    // 将四个byte拼接成一个int
    public int byte2Int(byte[] by)
    {
        int t1 = by[3] & 0xff;
        int t2 = by[2] & 0xff;
        int t3 = by[1] & 0xff;
        int t4 = by[0] & 0xff;
        return t1 << 24 | t2 << 16 | t3 << 8 | t4;
    }

    class myPanel extends JPanel
    {
        public int zoom(Graphics g, int[][] data_old, int height_old, int width_old,  int increase, int x_ratio, int y_ratio)
        {
            int height_new = height_old / y_ratio;
            int width_new = width_old / x_ratio;
            int[][] data_new = new int[height_new][width_new * 3];
            zoomdata_old_bilinear(data_new, width_new, height_new, data_old, width_old, height_old);

            for (int i = 0; i < height_new; i++)
            {
                for (int j = 0; j < width_new; j++)
                {
                    Color c = new Color(data_new[i][j * 3], data_new[i][j * 3 + 1], data_new[i][j * 3 + 2]);
                    g.setColor(c);
                    g.drawLine(j, height_new - i + increase, j, height_new - i + increase);
                }
            }
            return increase + height_new;
        }

        public void paint(Graphics g)
        {
            super.paint(g);
            // 读取数据
            int[][] data_old = readFile("E:\\VM\\电脑图标汇总icon\\better\\320_400\\Computer.bmp");
            // 判断是否存在
            if (data_old != null)
            {
                int height_old = data_old.length;
                int width_old = data_old[0].length / 3;

                this.setPreferredSize(new Dimension( width_old, height_old));

                for (int i = 0; i < height_old; i++)
                {
                    for (int j = 0; j < width_old; j++)
                    {
                        Color c = new Color(data_old[i][j * 3], data_old[i][j * 3 + 1], data_old[i][j * 3 + 2]);
                        g.setColor(c);
                        g.drawLine(j, height_old - i, j, height_old - i);
                    }
                }
                int increase;
                increase  = zoom(g, data_old, height_old, width_old, height_old, 2, 2);
                increase  = zoom(g, data_old, height_old, width_old, increase, 3, 2);
                increase  = zoom(g, data_old, height_old, width_old, increase, 4, 4);
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值