예제 #1
0
/**
 * Resizes the image so that the resulting sheet has a new size and the image
 * content is zoomed to fit best into the sheet, while keeping it's aspect ration.
 *
 * @param w the new width to resize to
 * @param h the new height to resize to
 */
void resize(int w, int h, struct IMAGE* image) {
    struct IMAGE newimage;
    int ww;
    int hh;
    float wRat;
    float hRat;
    
    if (verbose >= VERBOSE_NORMAL) {
        printf("resizing %dx%d -> %dx%d\n", image->width, image->height, w, h);
    }

    wRat = (float)w / image->width;
    hRat = (float)h / image->height;
    if (wRat < hRat) { // horizontally more shrinking/less enlarging is needed: fill width fully, adjust height
        ww = w;
        hh = image->height * w / image->width;
    } else if (hRat < wRat) {
        ww = image->width * h / image->height;
        hh = h;
    } else { // wRat == hRat
        ww = w;
        hh = h;
    }
    stretch(ww, hh, image);
    initImage(&newimage, w, h, image->bitdepth, image->color, image->background);
    centerImage(image, 0, 0, w, h, &newimage);
    replaceImage(image, &newimage);
}
void ExploreFrame::OnReplaceClicked( wxCommandEvent& event )
{
	const WADArchiveEntry& entry = GetSelectedEntry();
	wxFileName entryFN(entry.GetFileName());
	
	wxFileDialog fileDlg(this, wxString::Format(_("Select file to replace %s"), entry.GetFileName()), wxString(),
						 entryFN.GetFullName(), "*." + entryFN.GetExt(), wxFD_DEFAULT_STYLE  | wxFD_FILE_MUST_EXIST);
	if (fileDlg.ShowModal() == wxID_OK)
	{
		if (entryFN.GetExt().IsSameAs("png", false))
		{
			wxString imgErrors;

			// Do some sanity checks on the replacement image
			wxImage replaceImage(fileDlg.GetPath());
			if (replaceImage.IsOk())
			{
				if (replaceImage.HasAlpha())
					imgErrors += _("- Image may not have an alpha mask\n");

				wxMemoryOutputStream oStr;
				m_archive->Extract(entry, oStr);
				wxStreamBuffer* buffer = oStr.GetOutputStreamBuffer();
				wxMemoryInputStream iStr(buffer->GetBufferStart(), buffer->GetBufferSize());
				wxImage orgImage(iStr);
				if (orgImage.GetSize() != replaceImage.GetSize())
					imgErrors += wxString::Format(_("- Image has to be %dx%d in size\n"), orgImage.GetSize().x, orgImage.GetSize().y);

				if (orgImage.HasMask() != replaceImage.HasMask())
					imgErrors += _("- Image must have transparency\n");
			}
			else
				imgErrors = _("Image could not be loaded");

			if (!imgErrors.empty())
			{
				wxMessageDialog msgDlg(this, wxString::Format(
					_("Image Errors\n\nThe replacement image contains erros which might crash the game\n\n%s\n\nDo you want't to replace anyway?"), imgErrors),
					_("Warning"), wxICON_WARNING | wxYES_NO | wxNO_DEFAULT);
				msgDlg.SetYesNoLabels(_("Replace"), _("Don't Replace"));
				if (msgDlg.ShowModal() != wxID_YES)
					return;
			}
		}

		size_t index = (size_t) m_fileListCtrl->GetSelection().GetID() - 1;
		m_archive->ReplaceFiltered(index, fileDlg.GetPath());
		static_cast<FileDataModel*>(m_fileListCtrl->GetModel())->RowChanged(index);
		wxDataViewEvent evt(wxEVT_DATAVIEW_SELECTION_CHANGED);
		OnFileListSelectionChanged(evt);

		UpdateTitle();
	}
}
예제 #3
0
/**
 * Shifts the image.
 *
 * @param shiftX horizontal shifting
 * @param shiftY vertical shifting
 */
void shift(int shiftX, int shiftY, struct IMAGE* image) {
    struct IMAGE newimage;
    int x;
    int y;
    int pixel;

    // allocate new buffer's memory
    initImage(&newimage, image->width, image->height, image->bitdepth, image->color, image->background);
    
    for (y = 0; y < image->height; y++) {
        for (x = 0; x < image->width; x++) {
            pixel = getPixel(x, y, image);
            setPixel(pixel, x + shiftX, y + shiftY, &newimage);
        }
    }
    replaceImage(image, &newimage);
}
예제 #4
0
/**
 * Stretches the image so that the resulting image has a new size.
 *
 * @param w the new width to stretch to
 * @param h the new height to stretch to
 */
void stretch(int w, int h, struct IMAGE* image) {
    struct IMAGE newimage;
    int x;
    int y;
    int matrixX;
    int matrixY;
    int matrixWidth;
    int matrixHeight;
    int blockWidth;
    int blockHeight;
    int blockWidthRest;
    int blockHeightRest;
    int fillIndexWidth;
    int fillIndexHeight;
    int fill;
    int xx;
    int yy;
    int sum;
    int sumR;
    int sumG;
    int sumB;
    int sumCount;
    int pixel;

    if (verbose >= VERBOSE_MORE) {
        printf("stretching %dx%d -> %dx%d\n", image->width, image->height, w, h);
    }

    // allocate new buffer's memory
    initImage(&newimage, w, h, image->bitdepth, image->color, WHITE);
    
    blockWidth = image->width / w; // (0 if enlarging, i.e. w > image->width)
    blockHeight = image->height / h;

    if (w <= image->width) {
        blockWidthRest = (image->width) % w;
    } else { // modulo-operator doesn't work as expected: (3680 % 7360)==3680 ! (not 7360 as expected)
             // shouldn't always be a % b = b if a < b ?
        blockWidthRest = w;
    }

    if (h <= image->height) {
        blockHeightRest = (image->height) % h;
    } else {
        blockHeightRest = h;
    }

    // for each new pixel, get a matrix of pixels from which the new pixel should be derived
    // (when enlarging, this matrix is always of size 1x1)
    matrixY = 0;
    fillIndexHeight = 0;
    for (y = 0; y < h; y++) {
        fillIndexWidth = 0;
        matrixX = 0;
        if ( ( (y * blockHeightRest) / h ) == fillIndexHeight ) { // next fill index?
            // (If our optimizer is cool, the above "* blockHeightRest / h" will disappear
            // when images are enlarged, because in that case blockHeightRest = h has been set before,
            // thus we're in a Kripke-branch where blockHeightRest and h are the same variable.
            // No idea if gcc's optimizer does this...) (See again below.)
            fillIndexHeight++;
            fill = 1;
        } else {
            fill = 0;
        }
        matrixHeight = blockHeight + fill;
        for (x = 0; x < w; x++) {
            if ( ( (x * blockWidthRest) / w ) == fillIndexWidth ) { // next fill index?
                fillIndexWidth++;
                fill = 1;
            } else {
                fill = 0;
            }
            matrixWidth = blockWidth + fill;
            // if enlarging, map corrdinates directly
            if (blockWidth == 0) { // enlarging
                matrixX = (x * image->width) / w;
            }
            if (blockHeight == 0) { // enlarging
                matrixY = (y * image->height) / h;
            }
            
            // calculate average pixel value in source matrix
            if ((matrixWidth == 1) && (matrixHeight == 1)) { // optimization: quick version
                pixel = getPixel(matrixX, matrixY, image);
            } else {
                sumCount = 0;
                if (!image->color) {
                    sum = 0;
                    for (yy = 0; yy < matrixHeight; yy++) {
                        for (xx = 0; xx < matrixWidth; xx++) {
                            sum += getPixelGrayscale(matrixX + xx, matrixY + yy, image);
                            sumCount++;
                        }
                    }
                    sum = sum / sumCount;
                    pixel = pixelGrayscaleValue(sum);
                } else { // color
                    sumR = 0;
                    sumG = 0;
                    sumB = 0;
                    for (yy = 0; yy < matrixHeight; yy++) {
                        for (xx = 0; xx < matrixWidth; xx++) {
                            pixel = getPixel(matrixX + xx, matrixY + yy, image);
                            sumR += (pixel >> 16) & 0xff;
                            sumG += (pixel >> 8) & 0xff;
                            sumB += pixel & 0xff;
                            //sumR += getPixelComponent(matrixX + xx, matrixY + yy, RED, image);
                            //sumG += getPixelComponent(matrixX + xx, matrixY + yy, GREEN, image);
                            //sumB += getPixelComponent(matrixX + xx, matrixY + yy, BLUE, image);
                            sumCount++;
                        }
                    }
                    pixel = pixelValue( sumR/sumCount, sumG/sumCount, sumB/sumCount );
                }
            }
            setPixel(pixel, x, y, &newimage);
            
            // pixel may have resulted in a gray value, which will be converted to 1-bit
            // when the file gets saved, if .pbm format requested. black-threshold will apply.
            
            if (blockWidth > 0) { // shrinking
                matrixX += matrixWidth;
            }
        }
        if (blockHeight > 0) { // shrinking
            matrixY += matrixHeight;
        }
    }
    replaceImage(image, &newimage);
}