.PNG读写与图像缩放入门

小图片: IfranView:   

IrfanView是免费软件但不开源。下面的程序读取small.png,用最简单的方法放大到3.14倍后输出big.png:

/* 
https://www.nongnu.org/pngpp/ 在libpng上包了C++接口,用起来很方便。
安装与查看libpng++-dev
# apt-get install libpng++-dev
# dpkg -l | grep libpng
...
# dpkg -L libpng++-dev
/usr/include/png++ ...
# dpkg -L libpng-dev
/usr/include/libpng16
/usr/lib/x86_64-linux-gnu/libpng.a  ...
$ libpng-config --ldflags --cflags
-lpng16 -I/usr/include/libpng16
16是版本号
*/
#include <png++/image.hpp> // g++ 1.cpp -lpng16
using namespace png;
#define RGB rgb_pixel
#define ratio 3.14
int main() {
  image<RGB> small("small.png"); // 打开文件失败会throw
  const pixel_buffer<RGB>& s = small.get_pixbuf();
  int w = small.get_width(), h = small.get_height();
  int ww = int(ratio * w + 0.5), hh = (ratio * h + 0.5);
  image<RGB> big(ww, hh);
  pixel_buffer<RGB>& b = big.get_pixbuf();
  b[0][0] = RGB(255, 128, 0); // 试一下
  for (int yy = 0; yy < hh; yy++) {
    for (int xx = 0; xx < ww; xx++) {
      int x = int(xx / ratio + 0.5), y = int(yy / ratio + 0.5);
      if (x >= w) x = w - 1; if (y >= h) y = h - 1;
      b[yy][xx] = s[y][x];
    }
  }
  big.write("big.png");
}

结果: Lanczos:

avaneev/avir [作者] 带编译好的Linux和Windows下的exe: "imageresize <in-image> <out-image> <out-size> [options]"

还有C++源码(全在头文件里):

#include "avir.h"
avir::CImageResizer<> ImageResizer(8);
ImageResizer.resizeImage(InBuf, 640, 480, 0, OutBuf, 1024, 768, 3, 0);

AVIR works with header-less "raw" image buffers. If you are not too familiar with the low-level "packed interleaved"
image storage format, the `InBuf` is expected to be `w*h*c` elements in size, where `w` and `h` is the width and
the height of the image in pixels, respectively, and `c` is the number of color channels in the image.

In the example above, the size of the `InBuf` is `640*480*3=921600` elements. If you are working with 8-bit images,
the buffer and the elements should have the `uint8_t*` type; if you are working with 16-bit images, they should have
the `uint16_t*` type. Note that when processing 16-bit images, the value of `16` should be used in resizer's constructor.

Preliminary tests show that this library (compiled with Intel C++ Compiler 18.2 with AVX2 instructions enabled, without
explicit SIMD resizing code) can resize 8-bit RGB 5184x3456 (17.9 Mpixel) 3-channel image down to 1920x1280 (2.5 Mpixel)
image in 245 milliseconds, utilizing a single thread, on Intel Core i7-7700K processor-based system without overclocking.
This scales down to 74 milliseconds if 8 threads are utilized.

Multi-threaded operation is not provided by this library "out of the box". The multi-threaded (horizontally-threaded)
infrastructure is available, but requires additional system-specific interfacing code for engagement.

This library is capable of using SIMD floating-point types for internal variables. This means that up to 4 color channels
can be processed in parallel.

https://www.nongnu.org/pngpp/doc/0.2.9/pixel__buffer_8hpp_source.html
class basic_pixel_buffer {
 uint_32 m_width;
 uint_32 m_height;
 typedef std::vector<row_type> row_vec;
 row_vec m_rows;
};
这可不方便。

命令行工具放大结果:lowest quality(48,871 bytes), high(51,639)和ultra(52195):

调用函数:

#include "avir.h"
avir::CImageResizer<> ImageResizer(8);
ImageResizer.resizeImage(src, w, h, 0, dst, ww, hh, 3, 0);
或
#include "lancir.h"
avir::CLancIR ImageResizer;
ImageResizer.resizeImage(src, w, h, 0, dst, ww, hh, 0, 3);
注意两个resizeImage的参数不完全一样。CLancIR::resizeImage可以同时设置src和dst的width(stride).
lancir.h只有avir.h的1/3,2330行。虽然我看不懂,但我能把它变成1000行:-) 原作太爱换行了。
凑合一下:
uint8_t* src = new uint8_t[w * h * 3], *p = src;
for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) {
  auto& t = s[y][x]; *p++ = t.red; *p++ = t.green; *p++ = t.blue;
}
uint8_t* dst = new uint8_t[ww * hh * 3]; p = dst;
for (int y = 0; y < hh; y++) for (int x = 0; x < ww; x++) {
  b[y][x] = RGB(*p, p[1], p[2]); p += 3;
}

avir和lancir差不多: 从605x425缩小并Lanczos:

/usr/include/libpng16/png.h
/* This is for compression type. PNG 1.0-1.2 only define the single type. */
#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */
#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE

/usr/include/png++$ grep COMPRESS *.hpp
types.hpp:        compression_type_base    = PNG_COMPRESSION_TYPE_BASE,
types.hpp:        compression_type_default = PNG_COMPRESSION_TYPE_DEFAULT

只有base和default可用。base看意思是无损压缩。IrfanView可以设成0(none) - 9(best)
我那个程序,small.png用IrfanView不压缩另存的, 18KB; big.png不知道如何不压缩,13KB :-)

super-resolution · GitHub Topics [907 public repositories matching this topic... super hot :-)]

搜super-resolution online,包括但不限于:aiseesoft.com | DeepAI | Photobear [某软件安装后占据222MB还要上传图片?]

lanczos · GitHub Topics | Lanczos resampling - Detailed Pedia

FFmpeg Filters Documentation delogo derain

Source Code for Smooth Image Resampling [fairly-well-optimized, MMX加普通版, MMX about 32% faster]

Plain C Resampling DLL - CodeProject

posted @ 2023-01-08 11:33  Fun_with_Words  阅读(169)  评论(0编辑  收藏  举报









 张牌。