Changeset View
Changeset View
Standalone View
Standalone View
kstars/fitsviewer/fitsview.cpp
Show All 30 Lines | |||||
31 | #include <QtConcurrent> | 31 | #include <QtConcurrent> | ||
32 | #include <QScrollBar> | 32 | #include <QScrollBar> | ||
33 | #include <QToolBar> | 33 | #include <QToolBar> | ||
34 | #include <QGraphicsOpacityEffect> | 34 | #include <QGraphicsOpacityEffect> | ||
35 | #include <QApplication> | 35 | #include <QApplication> | ||
36 | #include <QGestureEvent> | 36 | #include <QGestureEvent> | ||
37 | 37 | | |||
38 | #define BASE_OFFSET 50 | 38 | #define BASE_OFFSET 50 | ||
39 | #define ZOOM_DEFAULT 100.0 | 39 | #define ZOOM_DEFAULT 100.0f | ||
40 | #define ZOOM_MIN 10 | 40 | #define ZOOM_MIN 10 | ||
41 | #define ZOOM_MAX 400 | 41 | #define ZOOM_MAX 400 | ||
42 | #define ZOOM_LOW_INCR 10 | 42 | #define ZOOM_LOW_INCR 10 | ||
43 | #define ZOOM_HIGH_INCR 50 | 43 | #define ZOOM_HIGH_INCR 50 | ||
44 | 44 | | |||
45 | namespace | 45 | namespace { | ||
46 | { | 46 | | ||
47 | // Derive the Green and Blue stretch parameters from their previous values and the | ||||
48 | // changes made to the Red parameters. We apply the same offsets used for Red to the | ||||
49 | // other channels' parameters, but clip them. | ||||
50 | void ComputeGBStretchParams(const StretchParams &newParams, StretchParams* params) { | ||||
51 | float shadow_diff = newParams.grey_red.shadows - params->grey_red.shadows; | ||||
52 | float highlight_diff = newParams.grey_red.highlights - params->grey_red.highlights; | ||||
53 | float midtones_diff = newParams.grey_red.midtones - params->grey_red.midtones; | ||||
54 | | ||||
55 | params->green.shadows = params->green.shadows + shadow_diff; | ||||
56 | params->green.shadows = KSUtils::clamp(params->green.shadows, 0.0f, 1.0f); | ||||
57 | params->green.highlights = params->green.highlights + highlight_diff; | ||||
58 | params->green.highlights = KSUtils::clamp(params->green.highlights, 0.0f, 1.0f); | ||||
59 | params->green.midtones = params->green.midtones + midtones_diff; | ||||
60 | params->green.midtones = std::max(params->green.midtones, 0.0f); | ||||
61 | | ||||
62 | params->blue.shadows = params->blue.shadows + shadow_diff; | ||||
63 | params->blue.shadows = KSUtils::clamp(params->blue.shadows, 0.0f, 1.0f); | ||||
64 | params->blue.highlights = params->blue.highlights + highlight_diff; | ||||
65 | params->blue.highlights = KSUtils::clamp(params->blue.highlights, 0.0f, 1.0f); | ||||
66 | params->blue.midtones = params->blue.midtones + midtones_diff; | ||||
67 | params->blue.midtones = std::max(params->blue.midtones, 0.0f); | ||||
68 | } | ||||
47 | 69 | | |||
48 | void doStretch(FITSData *data, QImage *outputImage, bool stretchOn) | 70 | } // namespace | ||
71 | | ||||
72 | // Runs the stretch checking the variables to see which parameters to use. | ||||
73 | // We call stretch even if we're not stretching, as the stretch code still | ||||
74 | // converts the image to the uint8 output image which will be displayed. | ||||
75 | // In that case, it will use an identity stretch. | ||||
76 | void FITSView::doStretch(FITSData *data, QImage *outputImage) | ||||
49 | { | 77 | { | ||
50 | if (outputImage->isNull()) | 78 | if (outputImage->isNull()) | ||
51 | return; | 79 | return; | ||
52 | Stretch stretch(static_cast<int>(data->width()), | 80 | Stretch stretch(static_cast<int>(data->width()), | ||
53 | static_cast<int>(data->height()), | 81 | static_cast<int>(data->height()), | ||
54 | data->channels(), data->property("dataType").toInt()); | 82 | data->channels(), data->property("dataType").toInt()); | ||
55 | if (stretchOn) | 83 | | ||
56 | stretch.setParams(stretch.computeParams(data->getImageBuffer())); | 84 | StretchParams tempParams; | ||
57 | stretch.run(data->getImageBuffer(), outputImage); | 85 | if (!stretchImage) | ||
86 | tempParams = StretchParams(); // Keeping it linear | ||||
87 | else if (autoStretch) | ||||
88 | { | ||||
89 | // Compute new auto-stretch params. | ||||
90 | stretchParams = stretch.computeParams(data->getImageBuffer()); | ||||
91 | tempParams = stretchParams; | ||||
58 | } | 92 | } | ||
93 | else | ||||
94 | // Use the existing stretch params. | ||||
95 | tempParams = stretchParams; | ||||
59 | 96 | | |||
60 | } // namespace | 97 | stretch.setParams(tempParams); | ||
98 | stretch.run(data->getImageBuffer(), outputImage, sampling); | ||||
99 | } | ||||
100 | | ||||
101 | // Store stretch parameters, and turn on stretching if it isn't already on. | ||||
102 | void FITSView::setStretchParams(const StretchParams& params) | ||||
103 | { | ||||
104 | if (imageData->channels() == 3) | ||||
105 | ComputeGBStretchParams(params, &stretchParams); | ||||
106 | | ||||
107 | stretchParams.grey_red = params.grey_red; | ||||
108 | stretchParams.grey_red.shadows = std::max(stretchParams.grey_red.shadows, 0.0f); | ||||
109 | stretchParams.grey_red.highlights = std::max(stretchParams.grey_red.highlights, 0.0f); | ||||
110 | stretchParams.grey_red.midtones = std::max(stretchParams.grey_red.midtones, 0.0f); | ||||
61 | 111 | | |||
112 | autoStretch = false; | ||||
113 | stretchImage = true; | ||||
114 | | ||||
115 | if (image_frame != nullptr && rescale(ZOOM_KEEP_LEVEL)) | ||||
116 | updateFrame(); | ||||
117 | } | ||||
118 | | ||||
119 | // Turn on or off stretching, and if on, use whatever parameters are currently stored. | ||||
120 | void FITSView::setStretch(bool onOff) | ||||
121 | { | ||||
122 | if (stretchImage != onOff) | ||||
123 | { | ||||
124 | stretchImage = onOff; | ||||
125 | if (image_frame != nullptr && rescale(ZOOM_KEEP_LEVEL)) | ||||
126 | updateFrame(); | ||||
127 | } | ||||
128 | } | ||||
129 | | ||||
130 | // Turn on stretching, using automatically generated parameters. | ||||
131 | void FITSView::setAutoStretchParams() | ||||
132 | { | ||||
133 | stretchImage = true; | ||||
134 | autoStretch = true; | ||||
135 | if (image_frame != nullptr && rescale(ZOOM_KEEP_LEVEL)) | ||||
136 | updateFrame(); | ||||
137 | } | ||||
62 | 138 | | |||
63 | FITSView::FITSView(QWidget * parent, FITSMode fitsMode, FITSScale filterType) : QScrollArea(parent), zoomFactor(1.2) | 139 | FITSView::FITSView(QWidget * parent, FITSMode fitsMode, FITSScale filterType) : QScrollArea(parent), zoomFactor(1.2) | ||
64 | { | 140 | { | ||
141 | // stretchImage is whether to stretch or not--the stretch may or may not use automatically generated parameters. | ||||
142 | // The user may enter his/her own. | ||||
65 | stretchImage = Options::autoStretch(); | 143 | stretchImage = Options::autoStretch(); | ||
144 | // autoStretch means use automatically-generated parameters. This is the default, unless the user overrides | ||||
145 | // by adjusting the stretchBar's sliders. | ||||
146 | autoStretch = true; | ||||
66 | 147 | | |||
67 | grabGesture(Qt::PinchGesture); | 148 | grabGesture(Qt::PinchGesture); | ||
68 | 149 | | |||
69 | image_frame.reset(new FITSLabel(this)); | 150 | image_frame.reset(new FITSLabel(this)); | ||
70 | filter = filterType; | 151 | filter = filterType; | ||
71 | mode = fitsMode; | 152 | mode = fitsMode; | ||
72 | 153 | | |||
73 | setBackgroundRole(QPalette::Dark); | 154 | setBackgroundRole(QPalette::Dark); | ||
▲ Show 20 Lines • Show All 133 Lines • ▼ Show 20 Line(s) | 258 | { | |||
207 | if (setBayerParams) | 288 | if (setBayerParams) | ||
208 | imageData->setBayerParams(¶m); | 289 | imageData->setBayerParams(¶m); | ||
209 | 290 | | |||
210 | fitsWatcher.setFuture(imageData->loadFITS(inFilename, silent)); | 291 | fitsWatcher.setFuture(imageData->loadFITS(inFilename, silent)); | ||
211 | } | 292 | } | ||
212 | 293 | | |||
213 | bool FITSView::loadFITSFromData(FITSData *data, const QString &inFilename) | 294 | bool FITSView::loadFITSFromData(FITSData *data, const QString &inFilename) | ||
214 | { | 295 | { | ||
296 | Q_UNUSED(inFilename) | ||||
215 | if (imageData != nullptr) | 297 | if (imageData != nullptr) | ||
216 | { | 298 | { | ||
217 | delete imageData; | 299 | delete imageData; | ||
218 | imageData = nullptr; | 300 | imageData = nullptr; | ||
219 | } | 301 | } | ||
220 | 302 | | |||
221 | if (floatingToolBar != nullptr) | 303 | if (floatingToolBar != nullptr) | ||
222 | { | 304 | { | ||
Show All 12 Lines | |||||
235 | imageData = data; | 317 | imageData = data; | ||
236 | 318 | | |||
237 | return processData(); | 319 | return processData(); | ||
238 | } | 320 | } | ||
239 | 321 | | |||
240 | bool FITSView::processData() | 322 | bool FITSView::processData() | ||
241 | { | 323 | { | ||
242 | // Set current width and height | 324 | // Set current width and height | ||
325 | if (!imageData) return false; | ||||
243 | currentWidth = imageData->width(); | 326 | currentWidth = imageData->width(); | ||
244 | currentHeight = imageData->height(); | 327 | currentHeight = imageData->height(); | ||
245 | 328 | | |||
246 | image_width = currentWidth; | 329 | int image_width = currentWidth; | ||
247 | image_height = currentHeight; | 330 | int image_height = currentHeight; | ||
248 | 331 | | |||
249 | image_frame->setSize(image_width, image_height); | 332 | image_frame->setSize(image_width, image_height); | ||
250 | 333 | | |||
251 | // Init the display image | 334 | // Init the display image | ||
252 | initDisplayImage(); | 335 | initDisplayImage(); | ||
253 | 336 | | |||
254 | imageData->applyFilter(filter); | 337 | imageData->applyFilter(filter); | ||
255 | 338 | | |||
▲ Show 20 Lines • Show All 144 Lines • ▼ Show 20 Line(s) | 470 | { | |||
400 | } | 483 | } | ||
401 | } | 484 | } | ||
402 | 485 | | |||
403 | template <typename T> | 486 | template <typename T> | ||
404 | bool FITSView::rescale(FITSZoom type) | 487 | bool FITSView::rescale(FITSZoom type) | ||
405 | { | 488 | { | ||
406 | if (rawImage.isNull()) | 489 | if (rawImage.isNull()) | ||
407 | return false; | 490 | return false; | ||
408 | if (true || image_height != imageData->height() || image_width != imageData->width()) | | |||
409 | { | | |||
410 | image_width = imageData->width(); | | |||
411 | image_height = imageData->height(); | | |||
412 | 491 | | |||
413 | initDisplayImage(); | 492 | if (!imageData) return false; | ||
493 | int image_width = imageData->width(); | ||||
494 | int image_height = imageData->height(); | ||||
495 | currentWidth = image_width; | ||||
496 | currentHeight = image_height; | ||||
414 | 497 | | |||
415 | if (isVisible()) | 498 | if (isVisible()) | ||
416 | emit newStatus(QString("%1x%2").arg(image_width).arg(image_height), FITS_RESOLUTION); | 499 | emit newStatus(QString("%1x%2").arg(image_width).arg(image_height), FITS_RESOLUTION); | ||
417 | } | | |||
418 | | ||||
419 | image_frame->setScaledContents(true); | | |||
420 | currentWidth = rawImage.width(); | | |||
421 | currentHeight = rawImage.height(); | | |||
422 | | ||||
423 | doStretch(imageData, &rawImage, stretchImage); | | |||
424 | | ||||
425 | scaledImage = QImage(); | | |||
426 | 500 | | |||
427 | switch (type) | 501 | switch (type) | ||
428 | { | 502 | { | ||
429 | case ZOOM_FIT_WINDOW: | 503 | case ZOOM_FIT_WINDOW: | ||
430 | if ((rawImage.width() > width() || rawImage.height() > height())) | 504 | if ((image_width > width() || image_height > height())) | ||
431 | { | 505 | { | ||
432 | double w = baseSize().width() - BASE_OFFSET; | 506 | double w = baseSize().width() - BASE_OFFSET; | ||
433 | double h = baseSize().height() - BASE_OFFSET; | 507 | double h = baseSize().height() - BASE_OFFSET; | ||
434 | 508 | | |||
435 | if (!firstLoad) | 509 | if (!firstLoad) | ||
436 | { | 510 | { | ||
437 | w = viewport()->rect().width() - BASE_OFFSET; | 511 | w = viewport()->rect().width() - BASE_OFFSET; | ||
438 | h = viewport()->rect().height() - BASE_OFFSET; | 512 | h = viewport()->rect().height() - BASE_OFFSET; | ||
Show All 26 Lines | |||||
465 | break; | 539 | break; | ||
466 | 540 | | |||
467 | default: | 541 | default: | ||
468 | currentZoom = 100; | 542 | currentZoom = 100; | ||
469 | 543 | | |||
470 | break; | 544 | break; | ||
471 | } | 545 | } | ||
472 | 546 | | |||
547 | initDisplayImage(); | ||||
548 | image_frame->setScaledContents(true); | ||||
549 | doStretch(imageData, &rawImage); | ||||
550 | scaledImage = QImage(); | ||||
473 | setWidget(image_frame.get()); | 551 | setWidget(image_frame.get()); | ||
474 | 552 | | |||
475 | if (type != ZOOM_KEEP_LEVEL) | 553 | // This is needed by fitstab, even if the zoom doesn't change, to change the stretch UI. | ||
476 | emit newStatus(QString("%1%").arg(currentZoom), FITS_ZOOM); | 554 | emit newStatus(QString("%1%").arg(currentZoom), FITS_ZOOM); | ||
477 | 555 | | |||
478 | return true; | 556 | return true; | ||
479 | } | 557 | } | ||
480 | 558 | | |||
481 | void FITSView::ZoomIn() | 559 | void FITSView::ZoomIn() | ||
482 | { | 560 | { | ||
483 | if (currentZoom >= ZOOM_DEFAULT && Options::limitedResourcesMode()) | 561 | if (currentZoom >= ZOOM_DEFAULT && Options::limitedResourcesMode()) | ||
Show All 9 Lines | |||||
493 | 571 | | |||
494 | emit actionUpdated("view_zoom_out", true); | 572 | emit actionUpdated("view_zoom_out", true); | ||
495 | if (currentZoom >= ZOOM_MAX) | 573 | if (currentZoom >= ZOOM_MAX) | ||
496 | { | 574 | { | ||
497 | currentZoom = ZOOM_MAX; | 575 | currentZoom = ZOOM_MAX; | ||
498 | emit actionUpdated("view_zoom_in", false); | 576 | emit actionUpdated("view_zoom_in", false); | ||
499 | } | 577 | } | ||
500 | 578 | | |||
501 | currentWidth = image_width * (currentZoom / ZOOM_DEFAULT); | 579 | if (!imageData) return; | ||
502 | currentHeight = image_height * (currentZoom / ZOOM_DEFAULT); | 580 | currentWidth = imageData->width() * (currentZoom / ZOOM_DEFAULT); | ||
581 | currentHeight = imageData->height() * (currentZoom / ZOOM_DEFAULT); | ||||
503 | 582 | | |||
504 | updateFrame(); | 583 | updateFrame(); | ||
505 | 584 | | |||
506 | emit newStatus(QString("%1%").arg(currentZoom), FITS_ZOOM); | 585 | emit newStatus(QString("%1%").arg(currentZoom), FITS_ZOOM); | ||
507 | } | 586 | } | ||
508 | 587 | | |||
509 | void FITSView::ZoomOut() | 588 | void FITSView::ZoomOut() | ||
510 | { | 589 | { | ||
511 | if (currentZoom <= ZOOM_DEFAULT) | 590 | if (currentZoom <= ZOOM_DEFAULT) | ||
512 | currentZoom -= ZOOM_LOW_INCR; | 591 | currentZoom -= ZOOM_LOW_INCR; | ||
513 | else | 592 | else | ||
514 | currentZoom -= ZOOM_HIGH_INCR; | 593 | currentZoom -= ZOOM_HIGH_INCR; | ||
515 | 594 | | |||
516 | if (currentZoom <= ZOOM_MIN) | 595 | if (currentZoom <= ZOOM_MIN) | ||
517 | { | 596 | { | ||
518 | currentZoom = ZOOM_MIN; | 597 | currentZoom = ZOOM_MIN; | ||
519 | emit actionUpdated("view_zoom_out", false); | 598 | emit actionUpdated("view_zoom_out", false); | ||
520 | } | 599 | } | ||
521 | 600 | | |||
522 | emit actionUpdated("view_zoom_in", true); | 601 | emit actionUpdated("view_zoom_in", true); | ||
523 | 602 | | |||
524 | currentWidth = image_width * (currentZoom / ZOOM_DEFAULT); | 603 | if (!imageData) return; | ||
525 | currentHeight = image_height * (currentZoom / ZOOM_DEFAULT); | 604 | currentWidth = imageData->width() * (currentZoom / ZOOM_DEFAULT); | ||
605 | currentHeight = imageData->height() * (currentZoom / ZOOM_DEFAULT); | ||||
526 | 606 | | |||
527 | updateFrame(); | 607 | updateFrame(); | ||
528 | 608 | | |||
529 | emit newStatus(QString("%1%").arg(currentZoom), FITS_ZOOM); | 609 | emit newStatus(QString("%1%").arg(currentZoom), FITS_ZOOM); | ||
530 | } | 610 | } | ||
531 | 611 | | |||
532 | void FITSView::ZoomToFit() | 612 | void FITSView::ZoomToFit() | ||
533 | { | 613 | { | ||
▲ Show 20 Lines • Show All 67 Lines • ▼ Show 20 Line(s) | |||||
601 | void FITSView::ZoomDefault() | 681 | void FITSView::ZoomDefault() | ||
602 | { | 682 | { | ||
603 | if (image_frame != nullptr) | 683 | if (image_frame != nullptr) | ||
604 | { | 684 | { | ||
605 | emit actionUpdated("view_zoom_out", true); | 685 | emit actionUpdated("view_zoom_out", true); | ||
606 | emit actionUpdated("view_zoom_in", true); | 686 | emit actionUpdated("view_zoom_in", true); | ||
607 | 687 | | |||
608 | currentZoom = ZOOM_DEFAULT; | 688 | currentZoom = ZOOM_DEFAULT; | ||
609 | currentWidth = image_width; | 689 | currentWidth = imageData->width(); | ||
610 | currentHeight = image_height; | 690 | currentHeight = imageData->height(); | ||
611 | 691 | | |||
612 | updateFrame(); | 692 | updateFrame(); | ||
613 | 693 | | |||
614 | emit newStatus(QString("%1%").arg(currentZoom), FITS_ZOOM); | 694 | emit newStatus(QString("%1%").arg(currentZoom), FITS_ZOOM); | ||
615 | 695 | | |||
616 | update(); | 696 | update(); | ||
617 | } | 697 | } | ||
618 | } | 698 | } | ||
▲ Show 20 Lines • Show All 122 Lines • ▼ Show 20 Line(s) | |||||
741 | } | 821 | } | ||
742 | 822 | | |||
743 | /** | 823 | /** | ||
744 | This Method draws a large Crosshair in the center of the image, it is like a set of axes. | 824 | This Method draws a large Crosshair in the center of the image, it is like a set of axes. | ||
745 | */ | 825 | */ | ||
746 | 826 | | |||
747 | void FITSView::drawCrosshair(QPainter * painter) | 827 | void FITSView::drawCrosshair(QPainter * painter) | ||
748 | { | 828 | { | ||
829 | if (!imageData) return; | ||||
830 | int image_width = imageData->width(); | ||||
831 | int image_height = imageData->height(); | ||||
749 | float scale = (currentZoom / ZOOM_DEFAULT); | 832 | float scale = (currentZoom / ZOOM_DEFAULT); | ||
750 | QPointF c = QPointF((qreal)image_width / 2 * scale, (qreal)image_height / 2 * scale); | 833 | QPointF c = QPointF((qreal)image_width / 2 * scale, (qreal)image_height / 2 * scale); | ||
751 | float midX = (float)image_width / 2 * scale; | 834 | float midX = (float)image_width / 2 * scale; | ||
752 | float midY = (float)image_height / 2 * scale; | 835 | float midY = (float)image_height / 2 * scale; | ||
753 | float maxX = (float)image_width * scale; | 836 | float maxX = (float)image_width * scale; | ||
754 | float maxY = (float)image_height * scale; | 837 | float maxY = (float)image_height * scale; | ||
755 | float r = 50 * scale; | 838 | float r = 50 * scale; | ||
756 | 839 | | |||
Show All 22 Lines | |||||
779 | Finally it draws the gridlines so that there will be 4 Gridlines on either side of the axes. | 862 | Finally it draws the gridlines so that there will be 4 Gridlines on either side of the axes. | ||
780 | Note: This has to start drawing at the center not at the edges because the center axes must | 863 | Note: This has to start drawing at the center not at the edges because the center axes must | ||
781 | be in the center of the image. | 864 | be in the center of the image. | ||
782 | */ | 865 | */ | ||
783 | 866 | | |||
784 | void FITSView::drawPixelGrid(QPainter * painter) | 867 | void FITSView::drawPixelGrid(QPainter * painter) | ||
785 | { | 868 | { | ||
786 | float scale = (currentZoom / ZOOM_DEFAULT); | 869 | float scale = (currentZoom / ZOOM_DEFAULT); | ||
787 | double width = image_width * scale; | 870 | float width = imageData->width() * scale; | ||
788 | double height = image_height * scale; | 871 | float height = imageData->height() * scale; | ||
789 | double cX = width / 2; | 872 | float cX = width / 2; | ||
790 | double cY = height / 2; | 873 | float cY = height / 2; | ||
791 | double deltaX = width / 10; | 874 | float deltaX = width / 10; | ||
792 | double deltaY = height / 10; | 875 | float deltaY = height / 10; | ||
793 | //draw the Axes | 876 | //draw the Axes | ||
794 | painter->setPen(QPen(Qt::red)); | 877 | painter->setPen(QPen(Qt::red)); | ||
795 | painter->drawText(cX - 30, height - 5, QString::number((int)((cX) / scale))); | 878 | painter->drawText(cX - 30, height - 5, QString::number((int)((cX) / scale))); | ||
796 | painter->drawText(width - 30, cY - 5, QString::number((int)((cY) / scale))); | 879 | painter->drawText(width - 30, cY - 5, QString::number((int)((cY) / scale))); | ||
797 | if (!showCrosshair) | 880 | if (!showCrosshair) | ||
798 | { | 881 | { | ||
799 | painter->drawLine(cX, 0, cX, height); | 882 | painter->drawLine(cX, 0, cX, height); | ||
800 | painter->drawLine(0, cY, width, cY); | 883 | painter->drawLine(0, cY, width, cY); | ||
Show All 40 Lines | |||||
841 | It determines the minimum and maximum RA and DEC, then it uses that information to | 924 | It determines the minimum and maximum RA and DEC, then it uses that information to | ||
842 | judge which gridLines to draw. Then it calls the drawEQGridlines methods below | 925 | judge which gridLines to draw. Then it calls the drawEQGridlines methods below | ||
843 | to draw gridlines at those specific RA and Dec values. | 926 | to draw gridlines at those specific RA and Dec values. | ||
844 | */ | 927 | */ | ||
845 | 928 | | |||
846 | void FITSView::drawEQGrid(QPainter * painter) | 929 | void FITSView::drawEQGrid(QPainter * painter) | ||
847 | { | 930 | { | ||
848 | float scale = (currentZoom / ZOOM_DEFAULT); | 931 | float scale = (currentZoom / ZOOM_DEFAULT); | ||
932 | int image_width = imageData->width(); | ||||
933 | int image_height = imageData->height(); | ||||
849 | 934 | | |||
850 | if (imageData->hasWCS()) | 935 | if (imageData->hasWCS()) | ||
851 | { | 936 | { | ||
852 | wcs_point * wcs_coord = imageData->getWCSCoord(); | 937 | wcs_point * wcs_coord = imageData->getWCSCoord(); | ||
853 | if (wcs_coord != nullptr) | 938 | if (wcs_coord != nullptr) | ||
854 | { | 939 | { | ||
855 | int size = image_width * image_height; | 940 | int size = image_width * image_height; | ||
856 | double maxRA = -1000; | 941 | double maxRA = -1000; | ||
▲ Show 20 Lines • Show All 171 Lines • ▼ Show 20 Line(s) | 1104 | { | |||
1028 | } | 1113 | } | ||
1029 | } | 1114 | } | ||
1030 | } | 1115 | } | ||
1031 | } | 1116 | } | ||
1032 | } | 1117 | } | ||
1033 | 1118 | | |||
1034 | bool FITSView::pointIsInImage(QPointF pt, bool scaled) | 1119 | bool FITSView::pointIsInImage(QPointF pt, bool scaled) | ||
1035 | { | 1120 | { | ||
1121 | int image_width = imageData->width(); | ||||
1122 | int image_height = imageData->height(); | ||||
1036 | float scale = (currentZoom / ZOOM_DEFAULT); | 1123 | float scale = (currentZoom / ZOOM_DEFAULT); | ||
1037 | if (scaled) | 1124 | if (scaled) | ||
1038 | return pt.x() < image_width * scale && pt.y() < image_height * scale && pt.x() > 0 && pt.y() > 0; | 1125 | return pt.x() < image_width * scale && pt.y() < image_height * scale && pt.x() > 0 && pt.y() > 0; | ||
1039 | else | 1126 | else | ||
1040 | return pt.x() < image_width && pt.y() < image_height && pt.x() > 0 && pt.y() > 0; | 1127 | return pt.x() < image_width && pt.y() < image_height && pt.x() > 0 && pt.y() > 0; | ||
1041 | } | 1128 | } | ||
1042 | 1129 | | |||
1043 | QPointF FITSView::getPointForGridLabel() | 1130 | QPointF FITSView::getPointForGridLabel() | ||
1044 | { | 1131 | { | ||
1132 | int image_width = imageData->width(); | ||||
1133 | int image_height = imageData->height(); | ||||
1045 | float scale = (currentZoom / ZOOM_DEFAULT); | 1134 | float scale = (currentZoom / ZOOM_DEFAULT); | ||
1046 | 1135 | | |||
1047 | //These get the maximum X and Y points in the list that are in the image | 1136 | //These get the maximum X and Y points in the list that are in the image | ||
1048 | QPointF maxXPt(image_width * scale / 2, image_height * scale / 2); | 1137 | QPointF maxXPt(image_width * scale / 2, image_height * scale / 2); | ||
1049 | for (auto &p : eqGridPoints) | 1138 | for (auto &p : eqGridPoints) | ||
1050 | { | 1139 | { | ||
1051 | if (p.x() > maxXPt.x() && pointIsInImage(p, true)) | 1140 | if (p.x() > maxXPt.x() && pointIsInImage(p, true)) | ||
1052 | maxXPt = p; | 1141 | maxXPt = p; | ||
▲ Show 20 Lines • Show All 395 Lines • ▼ Show 20 Line(s) | 1531 | { | |||
1448 | double scale = (currentZoom / ZOOM_DEFAULT); | 1537 | double scale = (currentZoom / ZOOM_DEFAULT); | ||
1449 | QPoint widgetPoint = w->mapFromParent(viewPortPoint); | 1538 | QPoint widgetPoint = w->mapFromParent(viewPortPoint); | ||
1450 | QPoint imagePoint = QPoint(widgetPoint.x() / scale, widgetPoint.y() / scale); | 1539 | QPoint imagePoint = QPoint(widgetPoint.x() / scale, widgetPoint.y() / scale); | ||
1451 | return imagePoint; | 1540 | return imagePoint; | ||
1452 | } | 1541 | } | ||
1453 | 1542 | | |||
1454 | void FITSView::initDisplayImage() | 1543 | void FITSView::initDisplayImage() | ||
1455 | { | 1544 | { | ||
1545 | // Account for leftover when sampling. Thus a 5-wide image sampled by 2 | ||||
1546 | // would result in a width of 3 (samples 0, 2 and 4). | ||||
1547 | int w = (imageData->width() + sampling - 1) / sampling; | ||||
1548 | int h = (imageData->height() + sampling - 1) / sampling; | ||||
1456 | if (imageData->channels() == 1) | 1549 | if (imageData->channels() == 1) | ||
1457 | { | 1550 | { | ||
1458 | rawImage = QImage(image_width, image_height, QImage::Format_Indexed8); | 1551 | rawImage = QImage(w, h, QImage::Format_Indexed8); | ||
1459 | 1552 | | |||
1460 | rawImage.setColorCount(256); | 1553 | rawImage.setColorCount(256); | ||
1461 | for (int i = 0; i < 256; i++) | 1554 | for (int i = 0; i < 256; i++) | ||
1462 | rawImage.setColor(i, qRgb(i, i, i)); | 1555 | rawImage.setColor(i, qRgb(i, i, i)); | ||
1463 | } | 1556 | } | ||
1464 | else | 1557 | else | ||
1465 | { | 1558 | { | ||
1466 | rawImage = QImage(image_width, image_height, QImage::Format_RGB32); | 1559 | rawImage = QImage(w, h, QImage::Format_RGB32); | ||
1467 | } | 1560 | } | ||
1468 | } | 1561 | } | ||
1469 | 1562 | | |||
1470 | /** | 1563 | /** | ||
1471 | The Following two methods allow gestures to work with trackpads. | 1564 | The Following two methods allow gestures to work with trackpads. | ||
1472 | Specifically, we are targeting the pinch events, so that if one is generated, | 1565 | Specifically, we are targeting the pinch events, so that if one is generated, | ||
1473 | Then the pinchTriggered method will be called. If the event is not a pinch gesture, | 1566 | Then the pinchTriggered method will be called. If the event is not a pinch gesture, | ||
1474 | then the event is passed back to the other event handlers. | 1567 | then the event is passed back to the other event handlers. | ||
▲ Show 20 Lines • Show All 244 Lines • Show Last 20 Lines |