进来看看到底你java处于一个什么样的水平把。

失落夏天
优质创作者: 操作系统技术领域
领域专家: 算法与数据结构技术领域
2013-02-08 05:00:39
有一个题目要求:
给一个指定的文件夹,递归遍历该文件夹以及该文件夹下子文件夹,找到所有格式为jpg或者JPG的图片,把所有尺寸为800*800的并且大于300K的图片压缩。
找到700*700的图片并且大于500K的压缩。
当然,给定的这个文件夹相当的大,所以算法必须尽可能的优化。
这其实是我工作中遇到的一个任务把,我用了半天的时间写了出来,第一次跑的时候用了大约1天的时间。
师傅是不满意的,第二天陪我一起修改了我的代码,第二次跑了一遍,只用了8个小时。
而且给我的感觉不仅仅是算法上的优化,他修改完的代码就是给人一种一目了然的感觉,这就让我强烈的感觉到了一个初级开发人员和高级开发人员的差别。
各位如果有兴趣的话可以尝试写一下我上面的那个题目,也可以在此基础上添加一些特色的东西。
最后我会把我的代码也发上来和大家对比一下。
把代码相互对比一下,这就好比人写的字,一看就能看出来自己处于一个什么样的水平。

200分赠送给算法最优化的那一位把。
...全文
835 35 打赏 收藏 举报
写回复
用AI写文章
35 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaobeiweng 2013-02-13
  • 打赏
  • 举报
回复
学习了。。······
yang3wei 2013-02-12
  • 打赏
  • 举报
回复
引用 33 楼 bao110908 的回复:
引用 31 楼 yang3wei 的回复:不过我有一些疑问: 1.class 前面带 static 是什么用法呢, 2.另外,宽高都拿到了,为什么还要将 宽高丢到一个 ImageInfo 对象里面呢,直接使用整形数组的结果不是更快捷? 1:内部类使用 static 的话,一般说明这个内部类不需要使用到外部类中的任何成员变量或者成员方法,也就是说这个内部类相对于……
感谢你的回复,学到了很多东西,呵呵,致敬!!
  • 打赏
  • 举报
回复
引用 31 楼 yang3wei 的回复:
不过我有一些疑问: 1.class 前面带 static 是什么用法呢, 2.另外,宽高都拿到了,为什么还要将 宽高丢到一个 ImageInfo 对象里面呢,直接使用整形数组的结果不是更快捷?
1:内部类使用 static 的话,一般说明这个内部类不需要使用到外部类中的任何成员变量或者成员方法,也就是说这个内部类相对于较为独立。如果有需要使用到外部类中数据的话,则需要把 static 去掉。不对外部类数据进行引用时,内部类应使用 static 类。 2:对于这个问题,举个很简单的例子,如果我还想获取图像长宽的 DPI 信息,以及颜色深度信息,或者是 JPEG 中 Exif 信息的话,那使用 int[] 就没办法表示了。 在面向对象程序设计中,返回值应尽量少使用 int[], String[], Map<String, Object> 之类的返回值,因为这样的返回值不是自描述的,为什么 int[0] 是表示长度呢?int[0] 就不能表示宽度么? 我很能理解你认为返回 int[] 的理由是什么,可能是因为 new 一个对象比较耗时和占用内存空间吧?实际上并不是这样的,new 一个对象而且这个类的构造中没有任何复杂耗时的操作,对于系统消耗来说可以忽略不计,而对于 HotSpot 的 JVM 而言,其内存分配的速度是大于 C 语言中 malloc 的内存分配速度。在 HotSpot 的 JVM 中一个 new 操作只占用了十几个 CPU 指令的时间。new 一个对象和 new 一个 int 数据的效率是等价的。 另外,new 一个对象所分配的内存更是可以忽略不计了,只是在 JVM 的 PermGen 方法区中多存放一些类的信息,以及方法的信息。
yang3wei 2013-02-12
  • 打赏
  • 举报
回复
引用 30 楼 bao110908 的回复:
至于 JPEG 的压缩那就复杂了,这需要对于 JPEG 图像格式有相当地了解,主要是对于无损压缩的 Huffman、行程进行编码进行优化,以及一些有损压缩技术,比如提高像素采样率,再使用 DCT 算法转换频率空间,再通过 DC 和 AC 系数进行图像处理和编码。
听起来就挺复杂的,感觉这个课题和算法沾边比 java 多
yang3wei 2013-02-12
  • 打赏
  • 举报
回复
引用 29 楼 bao110908 的回复:
取 JPEG 大小的话读取 JPEG header 中的部分就可以了,使用 JDK 的 ImageReader 读取的话还会读取其他的一些信息,这些信息在这个帖子中的意义不大。 在这里,我们只关心图像的大小,参考代码如下: Java code?12345678910111213141516171819202122232425262728293031323334……
很好很强大,长见识了,测了一下确实比 ImageReader 快了些 不过我有一些疑问: 1.class 前面带 static 是什么用法呢, 2.另外,宽高都拿到了,为什么还要将 宽高丢到一个 ImageInfo 对象里面呢,直接使用整形数组的结果不是更快捷?
  • 打赏
  • 举报
回复
至于 JPEG 的压缩那就复杂了,这需要对于 JPEG 图像格式有相当地了解,主要是对于无损压缩的 Huffman、行程进行编码进行优化,以及一些有损压缩技术,比如提高像素采样率,再使用 DCT 算法转换频率空间,再通过 DC 和 AC 系数进行图像处理和编码。
zqfddqr 2013-02-12
  • 打赏
  • 举报
回复
引用 22 楼 healer_kx 的回复:
引用 21 楼 zqfddqr 的回复:引用 5 楼 healer_kx 的回复:不会压缩。你压缩那部分自己写的?绝对不是自己写的 如果不是的话,那么对于Ruby来说,基本是一两行代码的事情啊。。。考个什么劲啊。
这东西jpg压缩自己写的能有sun的程序员效率高?
  • 打赏
  • 举报
回复
取 JPEG 大小的话读取 JPEG header 中的部分就可以了,使用 JDK 的 ImageReader 读取的话还会读取其他的一些信息,这些信息在这个帖子中的意义不大。 在这里,我们只关心图像的大小,参考代码如下:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class JpegImageMetaReader {

    private static final byte TAG_START = (byte)0xff;
    private static final byte START_OF_IMAGE = (byte)0xd8;
    private static final byte END_OF_IMAGE = (byte)0xd9;
    private static final byte START_OF_FRAME = (byte)0xc0;
    private static final byte RESTART_MODULO_START = (byte)0xd0;
    private static final byte RESTART_MODULO_END = (byte)0xd7;
    private static final byte START_OF_SCAN = (byte)0xda;

    public static void main(String[] args) throws IOException {
        InputStream in = null;
        try {
            in = new FileInputStream("d:/images.jpg");
            ImageInfo info = getImageInfo(in);
            System.out.println(info);
        } finally {
            if (in != null) {
                in.close();
            }
        }
    }

    public static ImageInfo getImageInfo(InputStream in) throws IOException {

        // 0-1: store JPEG tag
        // 2-3: store JPEG tag length
        // 4-5: store JPEG image height
        // 6-7: store JPEG image width
        byte[] seg = new byte[8];

        // read JPEG START_OF_IMAGE tag
        if (in.read(seg, 0, 2) == -1) {
            return null;
        }

        // if the first two bytes is not 0xff, 0xd8,
        // that is the image format is not JPEG
        if (seg[0] != TAG_START || seg[1] != START_OF_IMAGE) {
            return null;
        }

        while (true) {

            // read JPEG data tag, offset 0 must be 0xff
            if (in.read(seg, 0, 2) == -1) {
                return null;
            }

            // if tag does not start with 0xff,
            // the image format is not JPEG
            if (seg[0] != TAG_START) {
                return null;
            }

            // Ignore JPEG RESTART_MODULO tag
            if (seg[1] >= RESTART_MODULO_START && seg[1] <= RESTART_MODULO_END) {
                continue;
            }

            // find JPEG format START_OF_SCAN part,
            // data that starts with poisition is JPEG compression image data,
            // that never contains image meta information
            if (seg[1] == START_OF_SCAN) {
                return null;
            }

            // find JPEG format END_OF_IMAGE tag, finish scan
            if (seg[1] == END_OF_IMAGE) {
                return null;
            }

            // read JPEG data tag length
            if (in.read(seg, 2, 2) == -1) {
                return null;
            }

            // find START_OF_FRAME tag
            if (seg[1] == START_OF_FRAME) {
                break;
            }

            // skip JPEG data segement
            byte[] skip = new byte[toInt(seg, 2) - 2];
            if (in.read(skip) == -1) {
                return null;
            }
        }

        // ignore JPEG image precision byte
        if (in.read() == -1) {
            return null;
        }

        // read JPEG image height and width bytes
        if (in.read(seg, 4, 4) == -1) {
            return null;
        }
        return new ImageInfo(toInt(seg, 4), toInt(seg, 6));
    }

    private static int toInt(byte[] bys, int start) {
        return ((bys[start] & 0xff) << 8) | (bys[start + 1] & 0xff);
    }

    public static class ImageInfo {
        private int height;
        private int width;
        public ImageInfo(int height, int width) {
            super();
            this.height = height;
            this.width = width;
        }
        public int getWidth() {
            return width;
        }
        public int getHeight() {
            return height;
        }
        @Override
        public String toString() {
            return "height: " + height + ", width: " + width;
        }
    }
}
healer_kx 2013-02-12
  • 打赏
  • 举报
回复
引用 21 楼 zqfddqr 的回复:
引用 5 楼 healer_kx 的回复:不会压缩。你压缩那部分自己写的?绝对不是自己写的
如果不是的话,那么对于Ruby来说,基本是一两行代码的事情啊。。。考个什么劲啊。
失落夏天 2013-02-12
  • 打赏
  • 举报
回复
引用 27 楼 yang3wei 的回复:
引用 24 楼 AA5279AA 的回复:压缩图片的程序是借用网上的代码改的, 某些人很明显理解错了意思。 找到300K以上的压缩肯定是图片压缩,打包成rar文件没什么用。 另外我想表达的意思是一个看起来并不是很难的任务,但是其代码水平不一样,编出来的东西就是不一样。 效率以及代码的清晰度差别其实挺大的。 另外这绝对不是标题党,你想着能写出来和自己写出来对比别人……
压缩算法肯定不是我写的,如果是我写的话我就不会只是一个实习生的身份了。 但是这些算法网上有很多,可以借用他们的实验下,肯定能找到最合适的。
yang3wei 2013-02-12
  • 打赏
  • 举报
回复
引用 24 楼 AA5279AA 的回复:
压缩图片的程序是借用网上的代码改的, 某些人很明显理解错了意思。 找到300K以上的压缩肯定是图片压缩,打包成rar文件没什么用。 另外我想表达的意思是一个看起来并不是很难的任务,但是其代码水平不一样,编出来的东西就是不一样。 效率以及代码的清晰度差别其实挺大的。 另外这绝对不是标题党,你想着能写出来和自己写出来对比别人的代码差别是很大的。 我不相信一个人对比……
方便将压缩图片算法的原始版本贴出来么?
yang3wei 2013-02-12
  • 打赏
  • 举报
回复
引用 24 楼 AA5279AA 的回复:
压缩图片的程序是借用网上的代码改的, 某些人很明显理解错了意思。 找到300K以上的压缩肯定是图片压缩,打包成rar文件没什么用。 另外我想表达的意思是一个看起来并不是很难的任务,但是其代码水平不一样,编出来的东西就是不一样。 效率以及代码的清晰度差别其实挺大的。 另外这绝对不是标题党,你想着能写出来和自己写出来对比别人的代码差别是很大的。 我不相信一个人对比……
原来这个图片压缩的算法才是重点啊,其实你大可在刚开始的时候就说清楚一下么 另,这个图片压缩算法是你自己写的?
zhe8300975 2013-02-12
  • 打赏
  • 举报
回复
好好学习下!
失落夏天 2013-02-12
  • 打赏
  • 举报
回复
压缩图片的程序是借用网上的代码改的, 某些人很明显理解错了意思。 找到300K以上的压缩肯定是图片压缩,打包成rar文件没什么用。 另外我想表达的意思是一个看起来并不是很难的任务,但是其代码水平不一样,编出来的东西就是不一样。 效率以及代码的清晰度差别其实挺大的。 另外这绝对不是标题党,你想着能写出来和自己写出来对比别人的代码差别是很大的。 我不相信一个人对比别人和自己代码的时候看不出来水平的高低。
xtfgy2012 2013-02-11
  • 打赏
  • 举报
回复
楼主说的压缩是说要打成rar或zip包吗? 我怎么觉得他说的不是这个意思,他好像是说,如果图片大于某个值,比如300K就压缩下,是 要把这张图片压缩到300K以下,然后仍然是jpg图片,而不是打包! 压缩图片,图片肯定会失真,要让失真比较小,压缩速度又快,我倒觉得这是个比较不错的研究话题。
wanghy1979 2013-02-11
  • 打赏
  • 举报
回复
rar好用吗?java有自带zip包可以厌缩解厌文件,很简单
zqfddqr 2013-02-11
  • 打赏
  • 举报
回复
引用 5 楼 healer_kx 的回复:
不会压缩。你压缩那部分自己写的?
绝对不是自己写的
zqfddqr 2013-02-11
  • 打赏
  • 举报
回复
引用 2 楼 ticmy 的回复:
原来是标题党,还可以去c++区发一个“进来看看到底你c++处于一个什么样的水平把”,然后去.NET区发一个“进来看看到底你.NET处于一个什么样的水平把”
哈哈哈 表打击新人 楼主挺努力的啊
yang3wei 2013-02-11
  • 打赏
  • 举报
回复
引用 18 楼 wanghy1979 的回复:
引用 15 楼 yang3wei 的回复:引用 12 楼 wanghy1979 的回复:rar好用吗?java有自带zip包可以厌缩解厌文件,很简单 执行效率怎么样呢?用 jni 或着调用系统提供的命令行压缩工具感觉应该好些吧 不知道,没测过。如果没有特殊需要,我都是本着尽可能简单的原则编码
理解,为公司做事不比自己兴趣爱好,还是低调稳妥些好,免得给自己徒增麻烦。 譬如说 jni 虽然带来了高效老大很开心,但如果有一天老大让你对其他各个平台也做兼容,就得自己伤心了~
wanghy1979 2013-02-11
  • 打赏
  • 举报
回复
引用 15 楼 yang3wei 的回复:
引用 12 楼 wanghy1979 的回复:rar好用吗?java有自带zip包可以厌缩解厌文件,很简单 执行效率怎么样呢?用 jni 或着调用系统提供的命令行压缩工具感觉应该好些吧
不知道,没测过。如果没有特殊需要,我都是本着尽可能简单的原则编码
加载更多回复(15)

62,620

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧