图片压缩算法

通用裁图逻辑:

第一:我们先看下质量压缩方法:

private Bitmap compressImage(Bitmap image) {  
    ByteArrayOutputStream baos = new ByteArrayOutputStream();  
    //质量压缩方法,这里100表示不压缩,把压缩后的数据存入baos中  
    image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
    int options = 100;  
    while ( baos.size() / 1024>100) {  //循环判断如果压缩后图片是否大于100kb,大于继续压缩         
        baos.reset();//重置baos即清空baos  
        image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中  
        options -= 10;//每次都减少10  
    }  
    //把压缩后的数据baos存放到ByteArrayInputStream中  
    ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
    //把ByteArrayInputStream数据生成图片  
    Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);
    return bitmap;  
}  

第二:图片按比例大小压缩方法(根据路径获取图片并压缩):

private Bitmap getimage(String srcPath) {  
    BitmapFactory.Options newOpts = new BitmapFactory.Options();  
    //开始读入图片,把options.inJustDecodeBounds 设回true了 
    newOpts.inJustDecodeBounds = true;  
    //此时返回bm为空  
    Bitmap bitmap = BitmapFactory.decodeFile(srcPath,newOpts);
    newOpts.inJustDecodeBounds = false;  
    int w = newOpts.outWidth;  
    int h = newOpts.outHeight;  
    //现在主流手机比较多是800*480分辨率,所以高和宽我们设置为  
    float hh = 800f;//这里设置高度为800f  
    float ww = 480f;//这里设置宽度为480f  
    //缩放比,当前固定比例缩放,只用高或者宽其中一个数据计算即可  
    int be = 1;//be=1表示不缩放  
    //如果宽度大的话根据宽度固定大小缩放  
    if (w > h && w > ww) {
        be = (int) (newOpts.outWidth / ww); 
    //如果高度高的话根据宽度固定大小缩放   
    } else if (w < h && h > hh) {
        be = (int) (newOpts.outHeight / hh);  
    }  
    if (be <= 0)  
        be = 1;  
    newOpts.inSampleSize = be; //设置缩放比例  
    //重新读入图片,把options.inJustDecodeBounds设回false了  
    bitmap = BitmapFactory.decodeFile(srcPath, newOpts);  
    return compressImage(bitmap);//压缩比例后进行质量压缩  
}  

第三:图片按比例大小压缩方法(根据Bitmap图片压缩):

private Bitmap comp(Bitmap image) {  
      
    ByteArrayOutputStream baos = new ByteArrayOutputStream();         
    image.compress(Bitmap.CompressFormat.JPEG, 100, baos);  
    //判断如果图片大于1M,进行压缩避免在生成图片时溢出 
    if( bass.size() / 1024>1024) {   
        baos.reset();    //重置baos即清空baos  
        image.compress(Bitmap.CompressFormat.JPEG, 50, baos);   //这里压缩50%,把压缩后的数据存放到baos中  
    }  
    ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());  
    BitmapFactory.Options newOpts = new BitmapFactory.Options();  
    //开始读入图片,把options.inJustDecodeBounds 设回true了  
    newOpts.inJustDecodeBounds = true;  
    Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);  
    newOpts.inJustDecodeBounds = false;  
    int w = newOpts.outWidth;  
    int h = newOpts.outHeight;  
    //现在主流手机比较多是800*480分辨率,所以高和宽我们设置为  
    float hh = 800f;//这里设置高度为800f  
    float ww = 480f;//这里设置宽度为480f  
    //缩放比,当前固定比例缩放,只用高或者宽其中一个数据计算即可  
    int be = 1;   //be=1表示不缩放  
    // 如果宽度大的话根据宽度固定大小缩放  
    if (w > h && w > ww) {
        be = (int) (newOpts.outWidth / ww);  
    //如果高度高的话根据宽度固定大小缩放  z   
    } else if (w < h && h > hh) {
        be = (int) (newOpts.outHeight / hh);  
    }  
    if (be <= 0)  
        be = 1;  
    newOpts.inSampleSize = be;//设置缩放比例  
    //重新读入图片,把options.inJustDecodeBounds设回false了  
    isBm = new ByteArrayInputStream(baos.toByteArray());  
    bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);  
    return compressImage(bitmap);//压缩比例后进行质量压缩  
}  
常用简单方法:
  • 上面的几种方法是以字节流的方式裁剪图片。现在,再来看一种简单的裁剪方法,这个裁剪方法是通过Bitmap的创建功能来截取原图的部分数据:
 /** 图片裁剪:按指定大小裁剪 */
public Bitmap tailorImageByImgs(String srcPath, int hh, int ww) {
    BitmapFactory.Options newOpts = new BitmapFactory.Options();
    Bitmap bitmap = BitmapFactory.decodeFile(srcPath);

    int w = bitmap.getWidth();
    int h = bitmap.getHeight();

    int retX = w > ww ? (w - ww) / 2 : 0;//基于原图,取正方形左上角x坐标
    int retY = h > hh ? (h - hh) / 2 : 0;

    //下面这句是关键
    return Bitmap.createBitmap(bitmap, retX, retY, hh, ww, null, false);
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C语言中,可以使用各种算法来实现图片压缩函数。其中,常用的算法包括JPEG压缩和PNG压缩。 1. JPEG压缩:JPEG(Joint Photographic Experts Group)是一种广泛应用于图像压缩算法。在C语言中,可以使用libjpeg库来实现JPEG压缩。首先,你需要安装libjpeg库,并包含相应的头文件: ```c #include <stdio.h> #include <jpeglib.h> ``` 然后,可以使用以下代码片段来压缩图片: ```c void compress_image(const char* input_image, const char* output_image, int quality) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; FILE* infile, *outfile; JSAMPROW row_pointer[1]; int row_stride; if ((infile = fopen(input_image, "rb")) == NULL) { fprintf(stderr, "Can't open %s\n", input_image); return; } if ((outfile = fopen(output_image, "wb")) == NULL) { fprintf(stderr, "Can't create %s\n", output_image); fclose(infile); return; } cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); jpeg_stdio_dest(&cinfo, outfile); jpeg_read_header(&cinfo, TRUE); cinfo.image_quality = quality; jpeg_start_compress(&cinfo, TRUE); row_stride = cinfo.image_width * cinfo.input_components; unsigned char* buffer = (unsigned char*)malloc(row_stride); while (cinfo.next_scanline < cinfo.image_height) { row_pointer[0] = &buffer[cinfo.next_scanline * row_stride]; jpeg_write_scanlines(&cinfo, row_pointer, 1); } free(buffer); jpeg_finish_compress(&cinfo); fclose(outfile); jpeg_destroy_compress(&cinfo); fclose(infile); } ``` 上述代码中,`compress_image`函数接受输入图片路径、输出图片路径和压缩质量作为参数。它使用libjpeg库中的函数来进行图片压缩,并将压缩后的图片保存到指定路径。 2. PNG压缩:PNG(Portable Network Graphics)是一种无损的图像压缩格式。在C语言中,可以使用libpng库来实现PNG压缩。首先,你需要安装libpng库,并包含相应的头文件: ```c #include <stdio.h> #include <stdlib.h> #include <png.h> ``` 然后,可以使用以下代码片段来压缩图片: ```c void compress_image(const char* input_image, const char* output_image) { FILE* infile = fopen(input_image, "rb"); if (!infile) { fprintf(stderr, "Can't open %s\n", input_image); return; } png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { fclose(infile); fprintf(stderr, "png_create_write_struct failed\n"); return; } png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { fclose(infile); png_destroy_write_struct(&png_ptr, NULL); fprintf(stderr, "png_create_info_struct failed\n"); return; } if (setjmp(png_jmpbuf(png_ptr))) { fclose(infile); png_destroy_write_struct(&png_ptr, &info_ptr); fprintf(stderr, "Error during png creation\n"); return; } png_init_io(png_ptr, infile); png_read_info(png_ptr, info_ptr); png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); png_set_compression_strategy(png_ptr, Z_DEFAULT_STRATEGY); png_set_compression_mem_level(png_ptr, 8); png_set_compression_window_bits(png_ptr, 15); FILE* outfile = fopen(output_image, "wb"); if (!outfile) { fclose(infile); png_destroy_write_struct(&png_ptr, &info_ptr); fprintf(stderr, "Can't create %s\n", output_image); return; } png_set_write_fn(png_ptr, outfile, NULL, NULL); png_set_IHDR(png_ptr, info_ptr, png_get_image_width(png_ptr, info_ptr), png_get_image_height(png_ptr, info_ptr), png_get_bit_depth(png_ptr, info_ptr), PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_write_info(png_ptr, info_ptr); png_bytep* row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * png_get_image_height(png_ptr, info_ptr)); for (int y = 0; y < png_get_image_height(png_ptr, info_ptr); y++) { row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png_ptr, info_ptr)); } png_read_image(png_ptr, row_pointers); png_write_image(png_ptr, row_pointers); png_write_end(png_ptr, NULL); fclose(infile); fclose(outfile); png_destroy_write_struct(&png_ptr, &info_ptr); for (int y = 0; y < png_get_image_height(png_ptr, info_ptr); y++) { free(row_pointers[y]); } free(row_pointers); } ``` 上述代码中,`compress_image`函数接受输入图片路径和输出图片路径作为参数。它使用libpng库中的函数来进行图片压缩,并将压缩后的图片保存到指定路径。 以上是两种常用的图片压缩算法在C语言中的实现方法。你可以根据自己的需求选择其中一种算法来实现图片压缩函数。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值