js压缩图片 到固定像素以内,500k为例

JavaScript027

js压缩图片 到固定像素以内,500k为例,第1张

本文旨在探究js压缩图片的两种方式: 改变图片长宽 改变图片质量 ,和结合了以上两者的 最终方案

首先,阅读本文需要知道canvas的两个方法

这两个方法具体的说明可以在MDN上查看,关于图片压缩,也有很多现成的博客可以直接用。但是那些博客都有个问题,并没有关心之后图片的压缩质量。

我试着用一个现成的例子去跑了一下,一个1.7M的图片压缩到了23k,堪称像素级毁灭性破坏。

假如一张大图可能包含着很多文字等关键信息,必须上传之后使用方能清晰辨认。所以要压缩之后质量尽可能接近500k的。500k像素以内,就是若一张图宽度为1024,则高度不能超过500。因为图片有其他的信息,也是要占大小的。即不得大于 1024*500

所以,根据需求,上传图片不能超过500k的情况下尽可能保留图片的清晰度。当然如果可以的情况下用上面提到的 canvas.toDataURL 设置压缩程度为0.9,0.8试试看,图片质量可以接受,大小会有大幅度的缩小。

如果不压缩,靠调整图片长宽去控制上传大小呢?

原理很简单,就是靠不断地缩小限定的最大宽高,直到最终长宽的积小于规定的大小。

这种方法有可能最后得出的图片的大小会略大于规定大小,原因上文也提到过了,如果想使用这种方法,可自行再调整一下。

上面的方法有个问题,就是改变了图片的原始长宽。如果一个图的长宽足够大,压缩图片质量,糊一点但是内容看得清也是ok的嘛。所以,跟上面同理,我们可以不断调整图片的质量设定直到大小合适,那么,如何在图片上传之前知道图片的大小呢?

首先,需要知道的一点是,压缩之后拿到的base64字符串会转成blob对象,然后传给服务端。

可以查阅文档,blob对象有个属性是size

这个size就是上传之后实际的文件大小。

参照上面的思路,可以每次改变 canvas.toDataURL('image/' + fileType, level)level的值,去调整压缩图片质量,然后用blob对象的size去验证是否满足500k以内的需求。

关于 canvas.toDataURL 的level到底是怎么计算的,MDN文档里也没说,写了个循环一次减少0.1的level压缩了几个图片

用加减乘除算了一下,没找到规律,数学不好放弃了(这个东西好像也不是能观察出来的,看结果跟初始大小没啥关系)。

这里要注意的是,有可能遇到超大图片,0.1的level可能不足以压缩到500k,所以小于0.1的时候,改变level递减的差值继续压缩下去

在开始接收到图片的时候给一个loading增加用户的耐心好了,loading万岁~

其实单纯的压缩质量遇到稍大的图片,会导致页面高频计算,然后页面基本就用不了了- -。有尝试过用iphone的一个屏幕截图(10M左右),压的时候稍过一会,整个手机都在发烫,只能杀进程。

所以,若对长度没有特殊的限制,可以做一个缩放,去加快压缩的进度,提高能压缩的图片大小上限。

页面到了ios上还是不行- -,可以看到最后图片level为0.001,最长边为764。

问题还是循环次数还是过多,计算频率太高。从图中可看出,对于大图来说,初始设定的level和图片尺寸过于宽松,可以优化一下初始level和尺寸。

有的时候还会遇到一张图片无论如何也压不到500k,就是上一次和这次的压缩后大小没有变化,这种情况需要抛错,不让循环继续。

大图片的等待时间稍长,可以给用户先预览一个base64的图片增加等待耐心,方法名为 getImgBase64 ,这里都一并给出了

解决的隐患:上面这个方案会出现我需要一个500k的照片,压到了520k之后,再压了一次。有时候这最后的一次会特别夸张,直接将图片弄到了几十k。

参考了: https://github.com/WangYuLue/image-conversion

这个库里面有个方法 compressAccurately ,这个方法可以比较精准地压缩。偷偷翻了一下源码。

其实上一个方案的痛点就在于,如何在每一个压缩循环里处理尺寸和压缩比例。

总结

如有纰漏,欢迎指正

解:

加上7后能被3整除的整数的一般形式是:

3N-7(N是整数)

如果是三位数加上7后能被3整除

则有:

100≤3N-7≤1000

解得

36≤N≤335

36至335的整数共有:

335-36+1=300(个)

所以有300个三位数加上7后能被3整除

N=36时,3N-7=101

M=335时,3N-7=998

所以第一个符合条件的数是101,最后一个是998,

全部三位数分别是:

101

104

107

110

113

116

119

122

125

128

131

134

137

140

143

146

149

152

155

158

161

164

167

170

173

176

179

182

185

188

191

194

197

200

203

206

209

212

215

218

221

224

227

230

233

236

239

242

245

248

251

254

257

260

263

266

269

272

275

278

281

284

287

290

293

296

299

302

305

308

311

314

317

320

323

326

329

332

335

338

341

344

347

350

353

356

359

362

365

368

371

374

377

380

383

386

389

392

395

398

401

404

407

410

413

416

419

422

425

428

431

434

437

440

443

446

449

452

455

458

461

464

467

470

473

476

479

482

485

488

491

494

497

500

503

506

509

512

515

518

521

524

527

530

533

536

539

542

545

548

551

554

557

560

563

566

569

572

575

578

581

584

587

590

593

596

599

602

605

608

611

614

617

620

623

626

629

632

635

638

641

644

647

650

653

656

659

662

665

668

671

674

677

680

683

686

689

692

695

698

701

704

707

710

713

716

719

722

725

728

731

734

737

740

743

746

749

752

755

758

761

764

767

770

773

776

779

782

785

788

791

794

797

800

803

806

809

812

815

818

821

824

827

830

833

836

839

842

845

848

851

854

857

860

863

866

869

872

875

878

881

884

887

890

893

896

899

902

905

908

911

914

917

920

923

926

929

932

935

938

941

944

947

950

953

956

959

962

965

968

971

974

977

980

983

986

989

992

995

998

共300个

如果学习过等差数列求和公式,

它们的和=(101+998)*300/2=164850

如果没有学习过等差数列求和公式

可以用下列方法求和:

将上述数据从大到小排列后再与原数据对应相加

即:

101 + 998 = 1099

104 + 995 = 1099

107 + 992 = 1099

110 + 989 = 1099

113 + 986 = 1099

116 + 983 = 1099

119 + 980 = 1099

122 + 977 = 1099

125 + 974 = 1099

128 + 971 = 1099

131 + 968 = 1099

134 + 965 = 1099

137 + 962 = 1099

140 + 959 = 1099

143 + 956 = 1099

146 + 953 = 1099

149 + 950 = 1099

152 + 947 = 1099

155 + 944 = 1099

158 + 941 = 1099

161 + 938 = 1099

164 + 935 = 1099

167 + 932 = 1099

170 + 929 = 1099

173 + 926 = 1099

176 + 923 = 1099

179 + 920 = 1099

182 + 917 = 1099

185 + 914 = 1099

188 + 911 = 1099

191 + 908 = 1099

194 + 905 = 1099

197 + 902 = 1099

200 + 899 = 1099

203 + 896 = 1099

206 + 893 = 1099

209 + 890 = 1099

212 + 887 = 1099

215 + 884 = 1099

218 + 881 = 1099

221 + 878 = 1099

224 + 875 = 1099

227 + 872 = 1099

230 + 869 = 1099

233 + 866 = 1099

236 + 863 = 1099

239 + 860 = 1099

242 + 857 = 1099

245 + 854 = 1099

248 + 851 = 1099

251 + 848 = 1099

254 + 845 = 1099

257 + 842 = 1099

260 + 839 = 1099

263 + 836 = 1099

266 + 833 = 1099

269 + 830 = 1099

272 + 827 = 1099

275 + 824 = 1099

278 + 821 = 1099

281 + 818 = 1099

284 + 815 = 1099

287 + 812 = 1099

290 + 809 = 1099

293 + 806 = 1099

296 + 803 = 1099

299 + 800 = 1099

302 + 797 = 1099

305 + 794 = 1099

308 + 791 = 1099

311 + 788 = 1099

314 + 785 = 1099

317 + 782 = 1099

320 + 779 = 1099

323 + 776 = 1099

326 + 773 = 1099

329 + 770 = 1099

332 + 767 = 1099

335 + 764 = 1099

338 + 761 = 1099

341 + 758 = 1099

344 + 755 = 1099

347 + 752 = 1099

350 + 749 = 1099

353 + 746 = 1099

356 + 743 = 1099

359 + 740 = 1099

362 + 737 = 1099

365 + 734 = 1099

368 + 731 = 1099

371 + 728 = 1099

374 + 725 = 1099

377 + 722 = 1099

380 + 719 = 1099

383 + 716 = 1099

386 + 713 = 1099

389 + 710 = 1099

392 + 707 = 1099

395 + 704 = 1099

398 + 701 = 1099

401 + 698 = 1099

404 + 695 = 1099

407 + 692 = 1099

410 + 689 = 1099

413 + 686 = 1099

416 + 683 = 1099

419 + 680 = 1099

422 + 677 = 1099

425 + 674 = 1099

428 + 671 = 1099

431 + 668 = 1099

434 + 665 = 1099

437 + 662 = 1099

440 + 659 = 1099

443 + 656 = 1099

446 + 653 = 1099

449 + 650 = 1099

452 + 647 = 1099

455 + 644 = 1099

458 + 641 = 1099

461 + 638 = 1099

464 + 635 = 1099

467 + 632 = 1099

470 + 629 = 1099

473 + 626 = 1099

476 + 623 = 1099

479 + 620 = 1099

482 + 617 = 1099

485 + 614 = 1099

488 + 611 = 1099

491 + 608 = 1099

494 + 605 = 1099

497 + 602 = 1099

500 + 599 = 1099

503 + 596 = 1099

506 + 593 = 1099

509 + 590 = 1099

512 + 587 = 1099

515 + 584 = 1099

518 + 581 = 1099

521 + 578 = 1099

524 + 575 = 1099

527 + 572 = 1099

530 + 569 = 1099

533 + 566 = 1099

536 + 563 = 1099

539 + 560 = 1099

542 + 557 = 1099

545 + 554 = 1099

548 + 551 = 1099

551 + 548 = 1099

554 + 545 = 1099

557 + 542 = 1099

560 + 539 = 1099

563 + 536 = 1099

566 + 533 = 1099

569 + 530 = 1099

572 + 527 = 1099

575 + 524 = 1099

578 + 521 = 1099

581 + 518 = 1099

584 + 515 = 1099

587 + 512 = 1099

590 + 509 = 1099

593 + 506 = 1099

596 + 503 = 1099

599 + 500 = 1099

602 + 497 = 1099

605 + 494 = 1099

608 + 491 = 1099

611 + 488 = 1099

614 + 485 = 1099

617 + 482 = 1099

620 + 479 = 1099

623 + 476 = 1099

626 + 473 = 1099

629 + 470 = 1099

632 + 467 = 1099

635 + 464 = 1099

638 + 461 = 1099

641 + 458 = 1099

644 + 455 = 1099

647 + 452 = 1099

650 + 449 = 1099

653 + 446 = 1099

656 + 443 = 1099

659 + 440 = 1099

662 + 437 = 1099

665 + 434 = 1099

668 + 431 = 1099

671 + 428 = 1099

674 + 425 = 1099

677 + 422 = 1099

680 + 419 = 1099

683 + 416 = 1099

686 + 413 = 1099

689 + 410 = 1099

692 + 407 = 1099

695 + 404 = 1099

698 + 401 = 1099

701 + 398 = 1099

704 + 395 = 1099

707 + 392 = 1099

710 + 389 = 1099

713 + 386 = 1099

716 + 383 = 1099

719 + 380 = 1099

722 + 377 = 1099

725 + 374 = 1099

728 + 371 = 1099

731 + 368 = 1099

734 + 365 = 1099

737 + 362 = 1099

740 + 359 = 1099

743 + 356 = 1099

746 + 353 = 1099

749 + 350 = 1099

752 + 347 = 1099

755 + 344 = 1099

758 + 341 = 1099

761 + 338 = 1099

764 + 335 = 1099

767 + 332 = 1099

770 + 329 = 1099

773 + 326 = 1099

776 + 323 = 1099

779 + 320 = 1099

782 + 317 = 1099

785 + 314 = 1099

788 + 311 = 1099

791 + 308 = 1099

794 + 305 = 1099

797 + 302 = 1099

800 + 299 = 1099

803 + 296 = 1099

806 + 293 = 1099

809 + 290 = 1099

812 + 287 = 1099

815 + 284 = 1099

818 + 281 = 1099

821 + 278 = 1099

824 + 275 = 1099

827 + 272 = 1099

830 + 269 = 1099

833 + 266 = 1099

836 + 263 = 1099

839 + 260 = 1099

842 + 257 = 1099

845 + 254 = 1099

848 + 251 = 1099

851 + 248 = 1099

854 + 245 = 1099

857 + 242 = 1099

860 + 239 = 1099

863 + 236 = 1099

866 + 233 = 1099

869 + 230 = 1099

872 + 227 = 1099

875 + 224 = 1099

878 + 221 = 1099

881 + 218 = 1099

884 + 215 = 1099

887 + 212 = 1099

890 + 209 = 1099

893 + 206 = 1099

896 + 203 = 1099

899 + 200 = 1099

902 + 197 = 1099

905 + 194 = 1099

908 + 191 = 1099

911 + 188 = 1099

914 + 185 = 1099

917 + 182 = 1099

920 + 179 = 1099

923 + 176 = 1099

926 + 173 = 1099

929 + 170 = 1099

932 + 167 = 1099

935 + 164 = 1099

938 + 161 = 1099

941 + 158 = 1099

944 + 155 = 1099

947 + 152 = 1099

950 + 149 = 1099

953 + 146 = 1099

956 + 143 = 1099

959 + 140 = 1099

962 + 137 = 1099

965 + 134 = 1099

968 + 131 = 1099

971 + 128 = 1099

974 + 125 = 1099

977 + 122 = 1099

980 + 119 = 1099

983 + 116 = 1099

986 + 113 = 1099

989 + 110 = 1099

992 + 107 = 1099

995 + 104 = 1099

998 + 101 = 1099

所以要计算的和=1099*300/2=164850

(上述数据是在电子表格中自动产生的,如果手工打出这么多数据来就太烦了,呵呵)

供参考!JSWYC