Resize an image based on X,Y coordinates in CImg

45 Views Asked by At

I am trying to make an app that displays a large amount of data as an image. I am creating and displaying the image through CImg. Since it is a very large dataset (~4,000,000 data points) I need to be able to zoom into a certain location on the image. The function I have so far only resizes around the top left image of the screen. Code:

#include <iostream>
#include <winsock2.h>
#include <iphlpapi.h>
#include <icmpapi.h>
#include "cimg.h"
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")
#include <cmath>

using namespace cimg_library;



int size_x = 640;
int size_y = 480;
int size_z = 1;
int numberOfColorChannels = 3; // R G B
unsigned char initialValue = 0;

CImg<unsigned char> image(size_x, size_y, size_z, numberOfColorChannels, initialValue);
CImgDisplay display(image, "PingMap");

long float ycoor[10000000] = { 0 }, xcoorop[10000000], xcoor[10000000] = { 0 };
long int LO = 0;
char f;
char currentIp[15];
int pingtime;
unsigned int iterator;

void calcMap(int x, int (&rgb)[3]) {
    int r = 4.18485e-6 * x * x * x - 0.00532377 * x * x + 2.19321 * x - 39.1125;
    int g = 1.28826e-10 * x * x * x * x * x - 1.64251e-7 * x * x * x * x + 6.73208e-5 * x * x * x - 0.00808127 * x * x + 0.280643 * x - 1.61706;
    int b = 9.48804e-12 * x * x * x * x * x - 1.05015e-8 * x * x * x * x + 4.19544e-5 * x * x * x - 0.0232532 * x * x + 3.24907 * x + 30.466;
    std::cout << " " << max(0, r) << " " << max(0, g) << " " << max(0, b) << ", ";
    rgb[0] = max(0, r);
    rgb[1] = max(0, g);
    rgb[2] = max(0, b);
}

int ping(const char* ip) {
    HANDLE hIcmpFile;
    unsigned long ipaddr = INADDR_NONE;
    DWORD dwRetVal = 0;
    DWORD dwError = 0;
    char SendData[] = "Data Buffer";
    LPVOID ReplyBuffer = NULL;
    DWORD ReplySize = 0;

    ipaddr = inet_addr(ip);

    hIcmpFile = IcmpCreateFile();
    if (hIcmpFile == INVALID_HANDLE_VALUE) {
        printf("err ");
        return -1;
    }

    // Allocate space for a single reply.
    ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData) + 8;
    ReplyBuffer = (VOID*)malloc(ReplySize);
    if (ReplyBuffer == NULL) {
        printf("err ");
        return -1;
    }

    dwRetVal = IcmpSendEcho2(hIcmpFile, NULL, NULL, NULL,
        ipaddr, SendData, sizeof(SendData), NULL,
        ReplyBuffer, ReplySize, 1000);
    if (dwRetVal != 0) {
        PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
        struct in_addr ReplyAddr;
        ReplyAddr.S_un.S_addr = pEchoReply->Address;
        switch (pEchoReply->Status) {
        case IP_DEST_HOST_UNREACHABLE:
            printf("unreachable ");
            return -1;
        case IP_DEST_NET_UNREACHABLE:
            printf("unreachable ");
            return -1;
        case IP_REQ_TIMED_OUT:
            printf("unreachable ");
            return -1;
        default:
            break;
        }
        return pEchoReply->RoundTripTime;
    }
    else {
        printf("unreachable ");
        return -1;
    }
    printf("??? ");
    return -1;
}

void move(int j, float h, float& x, float& y)
{
    sprintf_s(currentIp, sizeof(currentIp), "%d.%d.%d.%d",
        (iterator & 0xFF000000) >> 24,
        (iterator & 0x00FF0000) >> 16,
        (iterator & 0x0000FF00) >> 8,
        (iterator & 0x000000FF));
    iterator++;
    pingtime = ping(currentIp);

    if (pingtime < 0) pingtime = 0;
    else pingtime = 432 - (pingtime * 10);

    if (j == 1) y -= h;
    else if (j == 2) x += h;
    else if (j == 3) y += h;
    else if (j == 4) x -= h;

    std::cout << currentIp << ", ";

    int col[3] = { 0,0,0 };
    calcMap(pingtime, col);
    std::cout << ", ";
    image.draw_point((int)x, (int)y, col);

    std::cout << pingtime << "\n";

    xcoor[LO] += x;
    ycoor[LO] += y;


    LO++;

}


void hilbert(int r, int d, int t, int u, int i, float h, float& x, float& y)
{
    if (i > 0)
    {
        i--;
        hilbert(d, r, u, t, i, h, x, y);
        move(r, h, x, y);
        hilbert(r, d, t, u, i, h, x, y);
        move(d, h, x, y);
        hilbert(r, d, t, u, i, h, x, y);
        move(t, h, x, y);
        hilbert(u, t, d, r, i, h, x, y);
    }
}
int factor = 0;
CImg<unsigned char> zoom(CImg<unsigned char> src, int dir) {
    factor += 10 * dir;
    CImg<unsigned char> img(src);
    img.resize(
        src.width() + factor,
        src.height() + factor,
        1,
        3);
    src.clear();
    src.draw_image(img);
    return src;
}

int main()
{
    int n;
    float h = 1;
    int r = 2, d = 3, t = 4, u = 1;  // X and Y Starting; H is how far it moves; r = rotation?; d, t, u Dosent matter;
    float xO = 0, yO = 0, x, y;
    n = 11;

    x = xO; y = yO;
    hilbert(r, d, t, u, n, h, x, y); // Start the Recursive alg;
    while (!display.is_closed()) {
        display.wait();
        if (display.button()) {
            if (display.button() & 1) imgdraw = zoom(image, 1);
            if (display.button() & 2) imgdraw = zoom(image, -1);
        }
        imgdraw.display(display);
    }
    return 0;
}

The zoom() function is what I have so far. I already tried using the centering_x and centering_y parameters, but that just made the image move to those coordinates after resizing. How do I make it resize around a certain point?

0

There are 0 best solutions below