Image scaling and rotating in C/C++

前端 未结 10 1612
情深已故
情深已故 2020-11-29 07:55

What is the best way to scale a 2D image array? For instance, suppose I have an image of 1024 x 2048 bytes, with each byte being a pixel. Each pixel is a grayscale level fro

相关标签:
10条回答
  • 2020-11-29 08:07

    CxImage is a free library for handling images, which can do what you want. I haven't personally used it except for trivial stuff, but I've seen it recommended repeatedly.

    0 讨论(0)
  • 2020-11-29 08:16

    It has not been mentioned yet, so I will point out that OpenCV has functions for scaling and rotating images, as well as an enormous number of other utilities. It may contain many features that are not relevant to the question, but it is very easy to setup and use for a library of its kind.

    You can try to implement transformations like this manually, but the simple approach to scaling and rotating will generally result in a significant loss of detail.

    Using OpenCV, scaling can be done like so:

    float scaleFactor = 0.68f;
    cv::Mat original = cv::imread(path);
    cv::Mat scaled;
    cv::resize(original, scaled, cv::Size(0, 0), scaleFactor, scaleFactor, cv::INTER_LANCZOS4);
    cv::imwrite("new_image.jpg", scaled);
    

    This scales the image down by a factor of 0.68 using Lanczos interpolation.

    I am not as familiar with rotations, but here's part of an example from one of the tutorials on the OpenCV website that I have edited down to the relevant parts. (The original had skew and translation in it also...)

    /// Compute a rotation matrix with respect to the center of the image
    Point center = Point(original.size().width / 2, original.size().height / 2);
    double angle = -50.0;
    double scale = 0.6;
    
    /// Get the rotation matrix with the specifications above
    Mat rot_mat( 2, 3, CV_32FC1 );
    rot_mat = getRotationMatrix2D(center, angle, scale);
    
    /// Rotate the image
    Mat rotated_image;
    warpAffine(src, rotated_image, rot_mat, src.size());
    

    OpenCV Website

    They have some very nice documentation too.

    0 讨论(0)
  • 2020-11-29 08:18

    What you're doing is mapping a set of input points to a set of output points. The first part of the problem is to determine the mapping for your resizing or rotation; the second part is to handle points that don't lie exactly on a pixel boundary.

    Mapping for a resize is easy:

    x' = x * (width' / width)
    y' = y * (height' / height)
    

    Mapping for rotation is only a little bit harder.

    x' = x * cos(a) + y * sin(a)
    y' = y * cos(a) - x * sin(a)
    

    The technique for determining the value of pixels that lie off the grid is called interpolation. There are many such algorithms, ranging widely in speed and final image quality. A few of them in increasing order of quality/time are nearest neighbor, bilinear, bicubic, and Sinc filter.

    0 讨论(0)
  • 2020-11-29 08:19

    There is no simple way of accomplishing this. Neither scaling nor rotating are trivial processes.

    It is therefore advisable to use a 2d imaging library. Magick++ can be an idea as divideandconquer.se point out, but there are others.

    0 讨论(0)
  • 2020-11-29 08:19

    Check out the Intel Performance Primitives. I have used it before and it produces near optimal performance on x86. There is also a test program that lets to play with the various algorithms.

    0 讨论(0)
  • 2020-11-29 08:20
    point scaling(point p,float sx,float sy) {
        point s;
    
        int c[1][3];
        int a[1][3]={p.x,p.y,1};
        int b[3][3]={sx,0,0,0,sy,0,0,0,1};
    
        multmat(a,b,c);
    
        s.x=c[0][0];
        s.y=c[0][1];
    
        return s;
    }
    
    0 讨论(0)
提交回复
热议问题