Jump to content

Stretching only part of the picture


Recommended Posts

Is there a way to stretch only parts of a picture, using guidelines?

Here is my image (a button) with red guidelines.

Posted Image

The image is divided into nine parts:

123

456

789

The way that the image parts should be stretched is:

1: none

2: horizontal

3: none

4: vertical

5: horizontal and vertical

6: vertical

7: none

8: horizontal

9: none

Here is an image of how I would want the picture stretched. The pink dots indicate the sections that were stretched.

Posted Image

Is there a way to load the image into Autoit, stretch it to a given width & height, and then apply it to a picture control?

I think that using GDI+ probably could work :mellow: , but I would have no clue to go about it. I know there are some GDI+ wizards around here... :)

I would appreciate at least some suggestions. :)

TIA, ChrisN

P.S. Although I am a newbie to the forums, I am definitely not a newbie to Autoit. :)

Link to comment
Share on other sites

To make it more clear, I would like a function that returns the stretched picture that could be placed in a picture control. Parameters would be something like this:

_ImageStretchGuidelines($InputImage,$LeftGuideline,$RightGuideline,$TopGuideline,$BottomGuideline)

_ImageStretchGuidelines($image,4,4,4,4)

$*Guideline parameters = Where to place the guidelines, in pixels from left, right, top, or bottom of image. E.g. if 4 would be passed for $LeftGuideline, it would place the guideline between pixel columns 4 & 5, counting from the left; and if 4 would be passed for $TopGuideline, it would place the guideline between pixel rows 4 & 5, counting from the top. For $RightGuideline, it would count columns going left from the right side of the image, & for $BottomGuideline, it would count rows up from the bottom of the image.

Monoscout: You would have to have 9 pics, one for each section, right? I did think of that, but it would be a lot more cumbersome.

TIA, ChrisN

Link to comment
Share on other sites

I know it can be done, because Windows does it. If you have used a theme editor like StyleBuilder, for buttons (or basically anything that can be different sizes [tabs, taskbar buttons, scrollbars, etc.]) you use one image and then set guidelines to determine how it should be stretched.

TIA, ChrisN

Link to comment
Share on other sites

I feel like I am having a conversation with myself here :), but anyway here goes....

I was looking in the help file at the GDI+ functions, and I came across the GDI+ Matrix commands. Maybe that would do the trick :mellow:? (Not that I would know how to do it, but it's an idea.)

I'm still thinking... :)

TIA, ChrisN

Link to comment
Share on other sites

First, get the w/h of the image, then split it into an array of images, e.g $aImage[9][5]

the first item in the array will look like this:

$aImage[0][0]=handle

$aImage[0][1]=left

$aImage[0][2]=top

$aImage[0][3]=width

$aImage[0][4]=height

Clone each part of the to get the handle, then work with them.

That is how I would do.

[edit] typo

Edited by taietel
Link to comment
Share on other sites

First, get the w/h of the image, then split it into an array of images, e.g $aImage[9][5]

the first item in the array will look like this:

$aImage[0][0]=handle

$aImage[0][1]=left

$aImage[0][2]=top

$aImage[0][3]=width

$aImage[0][4]=height

Clone each part of the to get the handle, then work with them.

That is how I would do.

[edit] typo

Ok, first, how would you go about splitting the image into multiple images?

Secondly, would there be a way to merge all the images back together when they have been stretched?

Edit: Are you saying to load the original pic into GDI+ and then use _GDIPlus_BitmapCloneArea() to get all the individual pictures, and then stretch them?

TIA, ChrisN

Edited by ChrisN
Link to comment
Share on other sites

Yes. Take this as a start:

#include <GDIPlus.au3>
_Image2Array(@ScriptDir&"\stop.bmp")
Func _Image2Array($sImage)
 Local $hImage, $iW, $iH, $aImages[9][5];handle,x,y,w,h
 _GDIPlus_Startup()
 $hImage = _GDIPlus_ImageLoadFromFile($sImage)
    $iW = _GDIPlus_ImageGetWidth ($hImage)
    $iH = _GDIPlus_ImageGetHeight ($hImage)
 ;image1
 $aImages[0][1] = 0;left
 $aImages[0][2] = 0;top
 $aImages[0][3] = 10;width
 $aImages[0][4] = 10;height
 $aImages[0][0] = _GDIPlus_BitmapCloneArea ($hImage, $aImages[0][1], $aImages[0][2], $aImages[0][3], $aImages[0][4], $GDIP_PXF24RGB)
 ;image2
 $aImages[1][1] = $aImages[0][3];left
 $aImages[1][2] = 0;top
 $aImages[1][3] = $iW-2*$aImages[0][3];width
 $aImages[1][4] = $aImages[0][4];height
 $aImages[1][0] = _GDIPlus_BitmapCloneArea ($hImage, $aImages[1][1], $aImages[1][2], $aImages[1][3], $aImages[1][4], $GDIP_PXF24RGB)
 ;image3
 $aImages[2][1] = $iW-$aImages[0][3];left
 $aImages[2][2] = 0;top
 $aImages[2][3] = $aImages[0][3];width
 $aImages[2][4] = $aImages[0][4];height
 $aImages[2][0] = _GDIPlus_BitmapCloneArea ($hImage, $aImages[2][1], $aImages[2][2], $aImages[2][3], $aImages[2][4], $GDIP_PXF24RGB)
 ; ... the rest of the array
 ;============= your code to work with ==============
 ;just for testing
 For $i=0 To 2
 _GDIPlus_ImageSaveToFile ($aImages[$i][0], @ScriptDir & "\img_no"&$i&".bmp")
 Next
 ;============= end your code to work with ==============
 For $i=0 To 2
 _GDIPlus_ImageDispose ($aImages[$i][0])
 Next
 _GDIPlus_ImageDispose ($hImage)
 _GDIPlus_Shutdown()
EndFunc

[edit] you only have to modify the image from the middle (in this example is just the first row), get the width and adjust left position of the third image.

Edited by taietel
Link to comment
Share on other sites

Yes. Take this as a start:

#include <GDIPlus.au3>
_Image2Array(@ScriptDir&"\stop.bmp")
Func _Image2Array($sImage)
 Local $hImage, $iW, $iH, $aImages[9][5];handle,x,y,w,h
 _GDIPlus_Startup()
 $hImage = _GDIPlus_ImageLoadFromFile($sImage)
    $iW = _GDIPlus_ImageGetWidth ($hImage)
    $iH = _GDIPlus_ImageGetHeight ($hImage)
 ;image1
 $aImages[0][1] = 0;left
 $aImages[0][2] = 0;top
 $aImages[0][3] = 10;width
 $aImages[0][4] = 10;height
 $aImages[0][0] = _GDIPlus_BitmapCloneArea ($hImage, $aImages[0][1], $aImages[0][2], $aImages[0][3], $aImages[0][4], $GDIP_PXF24RGB)
 ;image2
 $aImages[1][1] = $aImages[0][3];left
 $aImages[1][2] = 0;top
 $aImages[1][3] = $iW-2*$aImages[0][3];width
 $aImages[1][4] = $aImages[0][4];height
 $aImages[1][0] = _GDIPlus_BitmapCloneArea ($hImage, $aImages[1][1], $aImages[1][2], $aImages[1][3], $aImages[1][4], $GDIP_PXF24RGB)
 ;image3
 $aImages[2][1] = $iW-$aImages[0][3];left
 $aImages[2][2] = 0;top
 $aImages[2][3] = $aImages[0][3];width
 $aImages[2][4] = $aImages[0][4];height
 $aImages[2][0] = _GDIPlus_BitmapCloneArea ($hImage, $aImages[2][1], $aImages[2][2], $aImages[2][3], $aImages[2][4], $GDIP_PXF24RGB)
 ; ... the rest of the array
 ;============= your code to work with ==============
 ;just for testing
 For $i=0 To 2
 _GDIPlus_ImageSaveToFile ($aImages[$i][0], @ScriptDir & "\img_no"&$i&".bmp")
 Next
 ;============= end your code to work with ==============
 For $i=0 To 2
 _GDIPlus_ImageDispose ($aImages[$i][0])
 Next
 _GDIPlus_ImageDispose ($hImage)
 _GDIPlus_Shutdown()
EndFunc

[edit] you only have to modify the image from the middle (in this example is just the first row), get the width and adjust left position of the third image.

Thanks! :mellow:

I'll mess with this code & come back with questions tomorrow.

BTW: is there any way to merge the array of images back into one (after they have all been stretched)

TIA, ChrisN

Link to comment
Share on other sites

Here I stretch the image in the middle.

#include <GDIPlus.au3>
_Image2Array(@ScriptDir&"\stop.bmp")
Func _Image2Array($sImage)
 Local $hImage, $iW, $iH, $aImages[9][5];handle,x,y,w,h
 _GDIPlus_Startup()
 $hImage = _GDIPlus_ImageLoadFromFile($sImage)
    $iW = _GDIPlus_ImageGetWidth ($hImage)
    $iH = _GDIPlus_ImageGetHeight ($hImage)
 ;image1
 $aImages[0][1] = 0;left
 $aImages[0][2] = 0;top
 $aImages[0][3] = 10;width
 $aImages[0][4] = 10;height
 $aImages[0][0] = _GDIPlus_BitmapCloneArea ($hImage, $aImages[0][1], $aImages[0][2], $aImages[0][3], $aImages[0][4], $GDIP_PXF24RGB)
 ;image2
 $aImages[1][1] = $aImages[0][3];left
 $aImages[1][2] = 0;top
 $aImages[1][3] = $iW-2*$aImages[0][3];width
 $aImages[1][4] = $aImages[0][4];height
 $aImages[1][0] = _GDIPlus_BitmapCloneArea ($hImage, $aImages[1][1], $aImages[1][2], $aImages[1][3], $aImages[1][4], $GDIP_PXF24RGB)
 ;image3
 $aImages[2][1] = $iW-$aImages[0][3];left
 $aImages[2][2] = 0;top
 $aImages[2][3] = $aImages[0][3];width
 $aImages[2][4] = $aImages[0][4];height
 $aImages[2][0] = _GDIPlus_BitmapCloneArea ($hImage, $aImages[2][1], $aImages[2][2], $aImages[2][3], $aImages[2][4], $GDIP_PXF24RGB)
 ; ... the rest of the array
 ;============= your code to work with ==============
 ;stretch the second image
 Local $iStretch=200
 Local $hTmpBmp = _GDIPlus_BitmapCreateFromScan0($aImages[1][3]+$iStretch, $aImages[1][4])
 Local $hGraphic = _GDIPlus_ImageGetGraphicsContext($hTmpBmp)
 _GDIPlus_GraphicsClear($hGraphic,0xFFFFFFFF)
 _GDIPlus_GraphicsDrawImageRect($hGraphic, $aImages[1][0], $aImages[0][1], $aImages[1][2], $aImages[1][3]+$iStretch, $aImages[1][4]);$iWidth, $iHeight)
 $aImages[1][0] = $hTmpBmp
 ;just for testing
 For $i=0 To 2
 _GDIPlus_ImageSaveToFile ($aImages[$i][0], @ScriptDir & "\img_no"&$i&".bmp")
 Next
 ;============= end your code to work with ==============
 For $i=0 To 2
  _GDIPlus_ImageDispose ($aImages[$i][0])
 Next
 _GDIPlus_ImageDispose($hTmpBmp)
 _GDIPlus_GraphicsDispose($hGraphic)
 _GDIPlus_ImageDispose ($hImage)
 _GDIPlus_Shutdown()
EndFunc

Func _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $iStride = 0, $iPixelFormat = 0x0026200A, $pScan0 = 0)
 ;Thanks to Authenticity
 Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", $iStride, "int", $iPixelFormat, "ptr", $pScan0, "int*", 0)
 If @error Then Return SetError(@error, @extended, 0)
 Return $aResult[6]
EndFunc   ;==>_GDIPlus_BitmapCreateFromScan0

Yes, there is a way to merge those images back. But only if there is a will! :mellow:

[EDIT] Here is another version (with the whole array of images, but still you have to put them ALL together - here are the first 3 :) )

#include <GDIPlus.au3>
#include <Array.au3>
#include <Misc.au3>
_M();
;_Image2Array(@ScriptDir&"\test.bmp",300)
Func _Image2Array($sImage,$iStretch)
 Local $hImage, $iW, $iH, $aImages[9][5];handle,x,y,w,h
 _GDIPlus_Startup()
 $hImage = _GDIPlus_ImageLoadFromFile($sImage)
    $iW = _GDIPlus_ImageGetWidth ($hImage)
    $iH = _GDIPlus_ImageGetHeight ($hImage)
 $iL = 20;width/height of the corner
 For $j=0 To 8
  Switch $j;w
   Case 1,4,7
    $aImages[$j][3]=$iW-2*$iL
   Case Else
    $aImages[$j][3]=$iL
  EndSwitch
  Switch $j;h
   Case 0,1,2,6,7,8
    $aImages[$j][4]=$iL
   Case Else
    $aImages[$j][4]=$iH-2*$iL
  EndSwitch
  Switch $j;x
   Case 2,5,8
    $aImages[$j][1]=$iW-$aImages[$j][3]
   Case 1,4,7
    $aImages[$j][1]=$iL
   Case Else
    $aImages[$j][1]=0
  EndSwitch
  Switch $j;y
   Case 0,1,2
    $aImages[$j][2]=0
   Case 3,4,5
    $aImages[$j][2]=$iL
   Case Else
    $aImages[$j][2]=$iH-$iL
  EndSwitch
  $aImages[$j][0]=_GDIPlus_BitmapCloneArea ($hImage, $aImages[$j][1], $aImages[$j][2], $aImages[$j][3], $aImages[$j][4])
 Next

 ;============= your code to work with ==============
 ;stretch the second image
 Local $hTmpBmp = _GDIPlus_BitmapCreateFromScan0($aImages[1][3]+$iStretch, $aImages[1][4])
 Local $hGraphic = _GDIPlus_ImageGetGraphicsContext($hTmpBmp)
 _GDIPlus_GraphicsClear($hGraphic,0xFFFFFFFF)
 _GDIPlus_GraphicsSetSmoothingMode($hGraphic,2)
 _GDIPlus_GraphicsDrawImageRect($hGraphic, $aImages[1][0], $aImages[0][1], $aImages[1][2], $aImages[1][3]+$iStretch, $aImages[1][4])
 $aImages[1][0] = $hTmpBmp
 ;put the images back together
 Local $hFinalBmp = _GDIPlus_BitmapCreateFromScan0($iW+$iStretch-1, $aImages[0][4])
 Local $hFinalGraphic = _GDIPlus_ImageGetGraphicsContext($hFinalBmp)
 _GDIPlus_GraphicsClear($hFinalGraphic,0xFFFFFFFF)
 _GDIPlus_GraphicsSetSmoothingMode($hFinalGraphic,2)
 _GDIPlus_GraphicsDrawImage($hFinalGraphic, $aImages[0][0], $aImages[0][1], $aImages[0][2])
 _GDIPlus_GraphicsDrawImage($hFinalGraphic, $aImages[1][0], $aImages[1][1], $aImages[0][2])
 _GDIPlus_GraphicsDrawImage($hFinalGraphic, $aImages[2][0], $iW+$iStretch-$aImages[2][3]-1, $aImages[0][2])

 _GDIPlus_ImageSaveToFile ($hFinalBmp, @ScriptDir & "\stretched.bmp")
 ;============= end your code to work with ==============
 For $i=0 To 8
  _GDIPlus_ImageDispose ($aImages[$i][0])
 Next

 _GDIPlus_ImageDispose($hTmpBmp)
 _GDIPlus_GraphicsDispose($hGraphic)
 _GDIPlus_ImageDispose($hFinalBmp)
 _GDIPlus_GraphicsDispose($hFinalGraphic)
 _GDIPlus_ImageDispose ($hImage)
 _GDIPlus_Shutdown()
EndFunc

Func _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $iStride = 0, $iPixelFormat = 0x0026200A, $pScan0 = 0)
 ;Thanks to Authenticity
 Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", $iStride, "int", $iPixelFormat, "ptr", $pScan0, "int*", 0)
 If @error Then Return SetError(@error, @extended, 0)
 Return $aResult[6]
EndFunc   ;==>_GDIPlus_BitmapCreateFromScan0
Func _M()
 Local $iW=600, $iH=600
 Local $iL = 50;width of the corner=height
 Local $aImages[9][5]
 For $j=0 To 8
  Switch $j;w
   Case 1,4,7
    $aImages[$j][3]=$iW-2*$iL
   Case Else
    $aImages[$j][3]=$iL
  EndSwitch
  Switch $j;h
   Case 0,1,2,6,7,8
    $aImages[$j][4]=$iL
   Case Else
    $aImages[$j][4]=$iH-2*$iL
  EndSwitch
  Switch $j;x
   Case 2,5,8
    $aImages[$j][1]=$iW-$aImages[$j][3]
   Case 1,4,7
    $aImages[$j][1]=$iL
   Case Else
    $aImages[$j][1]=0
  EndSwitch
  Switch $j;y
   Case 0,1,2
    $aImages[$j][2]=0
   Case 3,4,5
    $aImages[$j][2]=$iL
   Case Else
    $aImages[$j][2]=$iH-$iL
  EndSwitch
  $aImages[$j][0]="handle"&$j
 Next
 _ArrayDisplay($aImages)
EndFunc

Regards,

taietel

Edited by taietel
Link to comment
Share on other sites

ChrisN, I've done part of your homework because it seems interesting:

#include <GDIPlus.au3>
;test.bmp is 512px x 512px
$sInputImage = _ImageStretchArray(@ScriptDir&"\test.bmp",-200,-200,50,@ScriptDir & "\stretched.bmp")
ShellExecute($sInputImage)
Exit

; #FUNCTION# ====================================================================================================================
; Name ..........: _ImageStretchArray
; Description ...: Stretch a image (no. 1,3,4,5,7), but not the corners (no. 0,2,6,8)
;       |0 1 2|
;       |3 4 5|
;       |6 7 8|
; Syntax ........: _ImageStretchArray($sImage[, $iStretchW = 0[, $iStretchH = 0[, $iCorner = 0[, $sOutImg = ""]]]])
; Parameters ....: $sImage              - Path to the image.
;                  $iStretchW           - [optional] An integer value. Default is 0.
;                  $iStretchH           - [optional] An integer value. Default is 0.
;                  $iCorner             - [optional] An integer value. Default is 0.
;                  $sOutImg             - [optional] Path to the output image. Default is @ScriptDir&"\stretched.bmp".
; Return values .: Path to the stretched image
; Author ........: Mihai Iancu (aka taietel)
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func _ImageStretchArray($sImage,$iStretchW=0,$iStretchH=0,$iCorner=0,$sOutImg="")
 If $sOutImg="" Then $sOutImg = @ScriptDir & "\stretched.bmp"
 Local $hImage, $iW, $iH, $aImages[9][5], $hTmpBmp[6], $hGraphic[6];handle,x,y,w,h
 _GDIPlus_Startup()
 $hImage = _GDIPlus_ImageLoadFromFile($sImage)
    $iW = _GDIPlus_ImageGetWidth ($hImage)
    $iH = _GDIPlus_ImageGetHeight ($hImage)
 For $j=0 To 8
  Switch $j;w
   Case 1,4,7
    $aImages[$j][3]=$iW-2*$iCorner
   Case Else
    $aImages[$j][3]=$iCorner
  EndSwitch
  Switch $j;h
   Case 0,1,2,6,7,8
    $aImages[$j][4]=$iCorner
   Case Else
    $aImages[$j][4]=$iH-2*$iCorner
  EndSwitch
  Switch $j;x
   Case 2,5,8
    $aImages[$j][1]=$iW-$iCorner
   Case 1,4,7
    $aImages[$j][1]=$iCorner
   Case Else
    $aImages[$j][1]=0
  EndSwitch
  Switch $j;y
   Case 0,1,2
    $aImages[$j][2]=0
   Case 3,4,5
    $aImages[$j][2]=$iCorner
   Case Else
    $aImages[$j][2]=$iH-$iCorner
  EndSwitch
  $aImages[$j][0]=_GDIPlus_BitmapCloneArea ($hImage, $aImages[$j][1], $aImages[$j][2], $aImages[$j][3], $aImages[$j][4])
 Next

 $hTmpBmp[0] = _GDIPlus_BitmapCreateFromScan0($iW+$iStretchW, $iH+$iStretchH)
 $hGraphic[0] = _GDIPlus_ImageGetGraphicsContext($hTmpBmp[0])
 _GDIPlus_GraphicsClear($hGraphic[0],0xFFFFFFFF)
 _GDIPlus_GraphicsSetSmoothingMode($hGraphic[0],2)

 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[0][0], $aImages[0][1], $aImages[0][2])
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[6][0], $aImages[6][1], $aImages[0][4]+$aImages[3][4]+$iStretchH)
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[2][0], $aImages[0][3]+$aImages[1][3]+$iStretchW, $aImages[0][2])
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[8][0], $aImages[0][3]+$aImages[1][3]+$iStretchW, $aImages[0][4]+$aImages[3][4]+$iStretchH);$iH+$iStretchH-$aImages[8][4])

 $hTmpBmp[1] = _GDIPlus_BitmapCreateFromScan0($iW+$iStretchW-2*$aImages[0][3], $aImages[0][4])
 $hGraphic[1] = _GDIPlus_ImageGetGraphicsContext($hTmpBmp[1])
 _GDIPlus_GraphicsClear($hGraphic[1],0xFFFFFFFF)
 _GDIPlus_GraphicsDrawImageRect($hGraphic[1], $aImages[1][0], $aImages[0][1], $aImages[1][2], $iW+$iStretchW-2*$aImages[0][3], $aImages[0][4])
 $aImages[1][0] = $hTmpBmp[1]
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[1][0], $aImages[1][1], $aImages[0][2])

 $hTmpBmp[2] = _GDIPlus_BitmapCreateFromScan0($aImages[0][3], $iH+$iStretchH-2*$aImages[0][4])
 $hGraphic[2] = _GDIPlus_ImageGetGraphicsContext($hTmpBmp[2])
 _GDIPlus_GraphicsClear($hGraphic[2],0xFFFFFFFF)
 _GDIPlus_GraphicsDrawImageRect($hGraphic[2], $aImages[3][0], $aImages[0][1], $aImages[1][2], $aImages[0][3], $iH+$iStretchH-2*$aImages[0][4])
 $aImages[3][0] = $hTmpBmp[2]
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[3][0], $aImages[0][1], $aImages[0][4])

 $hTmpBmp[3] = _GDIPlus_BitmapCreateFromScan0($iW+$iStretchW-2*$aImages[0][3], $iH+$iStretchH-2*$aImages[0][4])
 $hGraphic[3] = _GDIPlus_ImageGetGraphicsContext($hTmpBmp[3])
 _GDIPlus_GraphicsClear($hGraphic[3],0xFFFFFFFF)
 _GDIPlus_GraphicsDrawImageRect($hGraphic[3], $aImages[4][0], $aImages[0][1], $aImages[1][2], $iW+$iStretchW-2*$aImages[0][3],$iH+$iStretchH-2*$aImages[0][4])
 $aImages[4][0] = $hTmpBmp[3]
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[4][0], $aImages[0][3], $aImages[0][4])

 $hTmpBmp[4] = _GDIPlus_BitmapCreateFromScan0($aImages[0][3], $iH+$iStretchH-2*$aImages[0][4])
 $hGraphic[4] = _GDIPlus_ImageGetGraphicsContext($hTmpBmp[4])
 _GDIPlus_GraphicsClear($hGraphic[4],0xFFFFFFFF)
 _GDIPlus_GraphicsDrawImageRect($hGraphic[4], $aImages[5][0], $aImages[0][1], $aImages[1][2], $aImages[0][3], $iH+$iStretchH-2*$aImages[0][4])
 $aImages[5][0] = $hTmpBmp[4]
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[5][0], $aImages[0][3]+$aImages[1][3]+$iStretchW, $aImages[0][4])

 $hTmpBmp[5] = _GDIPlus_BitmapCreateFromScan0($iW+$iStretchW-2*$aImages[0][3], $aImages[0][4])
 $hGraphic[5] = _GDIPlus_ImageGetGraphicsContext($hTmpBmp[5])
 _GDIPlus_GraphicsClear($hGraphic[5],0xFFFFFFFF)
 _GDIPlus_GraphicsDrawImageRect($hGraphic[5], $aImages[7][0], $aImages[0][1], $aImages[1][2], $iW+$iStretchW-2*$aImages[0][3], $aImages[0][4])
 $aImages[7][0] = $hTmpBmp[5]
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[7][0], $aImages[0][3], $aImages[0][4]+$aImages[4][4]+$iStretchH)

 _GDIPlus_ImageSaveToFile ($hTmpBmp[0], $sOutImg)

 For $i=0 To 8
  _GDIPlus_ImageDispose ($aImages[$i][0])
 Next
 For $i=0 To 5
  _GDIPlus_ImageDispose($hTmpBmp[$i])
  _GDIPlus_GraphicsDispose($hGraphic[$i])
 Next

 _GDIPlus_ImageDispose ($hImage)
 _GDIPlus_Shutdown()
 Return $sOutImg
EndFunc

Func _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $iStride = 0, $iPixelFormat = 0x0026200A, $pScan0 = 0)
 ;Thanks to Authenticity
 Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", $iStride, "int", $iPixelFormat, "ptr", $pScan0, "int*", 0)
 If @error Then Return SetError(@error, @extended, 0)
 Return $aResult[6]
EndFunc   ;==>_GDIPlus_BitmapCreateFromScan0

I'll try to optimize it (had some spare time at work).

[EDIT] Try it now.

Edited by taietel
Link to comment
Share on other sites

First, let me say :mellow:THANKS A LOT!!!:cheer:This is better than I could do!!

Now, let me pick apart your script.;) I found a few problems with it:

1. You are assuming that the corners are the same size all around. What if one side of the pic has a thicker border than the other side... (I have no problems with that, and I probably can change that if I study your script long enough. :blink:)

2. The stretched image looks like it had jpeg compression on the parts that were stretched.

Example:

This is the original image...

Posted Image

and this is the stretched one.

Posted Image

Notice the artifacts at the bottoms of the 5 stretched sections, and also the numbers are blurred.

Here is the image manually stretched in MSPaint:

Posted Image

That's more what I expected to see.

3. I just noticed that the stretched image is larger than what I thought it would be. My original pic is 100x100 & I used 100x200 for your function. It must add the height/width onto the original height/width. (Something I can probably fix.)

Anyway, thanks for the code. It will be useful!

:):):party::)

ChrisN

Link to comment
Share on other sites

Try now (here I made some modifications for png and also corrected some "bugs") and see if it fits:

#include <GDIPlus.au3>
$sInputImage = _ImageStretchArray(@ScriptDir&"\test.png",100,-50,100,@ScriptDir & "\stretched.png")
ShellExecute($sInputImage)
Exit

; #FUNCTION# ====================================================================================================================
; Name ..........: _ImageStretchArray
; Description ...: Stretch a image (no. 1,3,4,5,7), but not the corners (no. 0,2,6,8)
;       |0 1 2|
;       |3 4 5|
;       |6 7 8|
; Syntax ........: _ImageStretchArray($sImage[, $iStretchW = 0[, $iStretchH = 0[, $iCorner = 0[, $sOutImg = ""]]]])
; Parameters ....: $sImage              - Path to the image.
;                  $iStretchW           - [optional] An integer value. Default is 0.
;                  $iStretchH           - [optional] An integer value. Default is 0.
;                  $iCorner             - [optional] An integer value. Default is 0.
;                  $sOutImg             - [optional] Path to the output image. Default is @ScriptDir&"\stretched.png".
; Return values .: Path to the stretched image
; Author ........: Mihai Iancu (aka taietel)
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func _ImageStretchArray($sImage,$iStretchW=0,$iStretchH=0,$iCorner=0,$sOutImg="")
 If $sOutImg="" Then $sOutImg = @ScriptDir & "\stretched.png"
 Local $hImage, $aImages[9][5], $hTmpBmp[6], $hGraphic[6]
 Local $iW, $iH
 _GDIPlus_Startup()
 $hImage = _GDIPlus_ImageLoadFromFile($sImage)
    $iW = _GDIPlus_ImageGetWidth ($hImage)
    $iH = _GDIPlus_ImageGetHeight ($hImage)
 For $j=0 To 8
  Switch $j;w
   Case 1,4,7
    $aImages[$j][3]=$iW-2*$iCorner
   Case Else
    $aImages[$j][3]=$iCorner
  EndSwitch
  Switch $j;h
   Case 0,1,2,6,7,8
    $aImages[$j][4]=$iCorner
   Case Else
    $aImages[$j][4]=$iH-2*$iCorner
  EndSwitch
  Switch $j;x
   Case 2,5,8
    $aImages[$j][1]=$iW-$iCorner
   Case 1,4,7
    $aImages[$j][1]=$iCorner
   Case Else
    $aImages[$j][1]=0
  EndSwitch
  Switch $j;y
   Case 0,1,2
    $aImages[$j][2]=0
   Case 3,4,5
    $aImages[$j][2]=$iCorner
   Case Else
    $aImages[$j][2]=$iH-$iCorner
  EndSwitch
  $aImages[$j][0]=_GDIPlus_BitmapCloneArea ($hImage, $aImages[$j][1], $aImages[$j][2], $aImages[$j][3], $aImages[$j][4],$GDIP_PXF32ARGB)
 Next

 ;create an empty bitmap, stretched
 $hTmpBmp[0] = _GDIPlus_BitmapCreateFromScan0($iW+$iStretchW, $iH+$iStretchH)
 $hGraphic[0] = _GDIPlus_ImageGetGraphicsContext($hTmpBmp[0])
 _GDIPlus_GraphicsClear($hGraphic[0],0x00FFFFFF)
 _GDIPlus_GraphicsSetSmoothingMode($hGraphic[0],2)

 ;and fill it with array of images
 ;first, draw those pieces that are unchanged
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[0][0], $aImages[0][1], $aImages[0][2])
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[6][0], $aImages[6][1], $aImages[0][4]+$aImages[3][4]+$iStretchH)
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[2][0], $aImages[0][3]+$aImages[1][3]+$iStretchW, $aImages[0][2])
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[8][0], $aImages[0][3]+$aImages[1][3]+$iStretchW, $aImages[0][4]+$aImages[3][4]+$iStretchH)
 ;then those that are stretched
 $hTmpBmp[1] = _GDIPlus_BitmapCreateFromScan0($iW+$iStretchW-2*$aImages[0][3], $aImages[0][4])
 $hGraphic[1] = _GDIPlus_ImageGetGraphicsContext($hTmpBmp[1])
 _GDIPlus_GraphicsClear($hGraphic[1],0x00FFFFFF)
 _GDIPlus_GraphicsDrawImageRect($hGraphic[1], $aImages[1][0], $aImages[0][1], $aImages[1][2], $iW+$iStretchW-2*$aImages[0][3]+1, $aImages[0][4])
 $aImages[1][0] = $hTmpBmp[1]
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[1][0], $aImages[1][1], $aImages[0][2])

 $hTmpBmp[2] = _GDIPlus_BitmapCreateFromScan0($aImages[0][3], $iH+$iStretchH-2*$aImages[0][4])
 $hGraphic[2] = _GDIPlus_ImageGetGraphicsContext($hTmpBmp[2])
 _GDIPlus_GraphicsClear($hGraphic[2],0x00FFFFFF)
 _GDIPlus_GraphicsDrawImageRect($hGraphic[2], $aImages[3][0], $aImages[0][1], $aImages[1][2], $aImages[0][3], $iH+$iStretchH-2*$aImages[0][4]+1)
 $aImages[3][0] = $hTmpBmp[2]
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[3][0], $aImages[0][1], $aImages[0][4])

 $hTmpBmp[3] = _GDIPlus_BitmapCreateFromScan0($iW+$iStretchW-2*$aImages[0][3], $iH+$iStretchH-2*$aImages[0][4])
 $hGraphic[3] = _GDIPlus_ImageGetGraphicsContext($hTmpBmp[3])
 _GDIPlus_GraphicsClear($hGraphic[3],0x00FFFFFF)
 _GDIPlus_GraphicsDrawImageRect($hGraphic[3], $aImages[4][0], $aImages[0][1], $aImages[1][2], $iW+$iStretchW-2*$aImages[0][3]+1,$iH+$iStretchH-2*$aImages[0][4]+1)
 $aImages[4][0] = $hTmpBmp[3]
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[4][0], $aImages[0][3], $aImages[0][4])

 $hTmpBmp[4] = _GDIPlus_BitmapCreateFromScan0($aImages[0][3], $iH+$iStretchH-2*$aImages[0][4])
 $hGraphic[4] = _GDIPlus_ImageGetGraphicsContext($hTmpBmp[4])
 _GDIPlus_GraphicsClear($hGraphic[4],0x00FFFFFF)
 _GDIPlus_GraphicsDrawImageRect($hGraphic[4], $aImages[5][0], $aImages[0][1], $aImages[1][2], $aImages[0][3], $iH+$iStretchH-2*$aImages[0][4]+1)
 $aImages[5][0] = $hTmpBmp[4]
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[5][0], $aImages[0][3]+$aImages[1][3]+$iStretchW, $aImages[0][4])

 $hTmpBmp[5] = _GDIPlus_BitmapCreateFromScan0($iW+$iStretchW-2*$aImages[0][3], $aImages[0][4])
 $hGraphic[5] = _GDIPlus_ImageGetGraphicsContext($hTmpBmp[5])
 _GDIPlus_GraphicsClear($hGraphic[5],0x00FFFFFF)
 _GDIPlus_GraphicsDrawImageRect($hGraphic[5], $aImages[7][0], $aImages[0][1], $aImages[1][2], $iW+$iStretchW-2*$aImages[0][3]+1, $aImages[0][4])
 $aImages[7][0] = $hTmpBmp[5]
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[7][0], $aImages[0][3], $aImages[0][4]+$aImages[4][4]+$iStretchH)

 ;save the file
 _GDIPlus_ImageSaveToFile ($hTmpBmp[0], $sOutImg)
 ;clean up
 For $i=0 To 8
  _GDIPlus_ImageDispose ($aImages[$i][0])
 Next
 For $i=0 To 5
  _GDIPlus_ImageDispose($hTmpBmp[$i])
  _GDIPlus_GraphicsDispose($hGraphic[$i])
 Next

 _GDIPlus_ImageDispose ($hImage)
 _GDIPlus_Shutdown()
 Return $sOutImg
EndFunc

Func _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $iStride = 0, $iPixelFormat = 0x0026200A, $pScan0 = 0)
 ;Thanks to Authenticity
 Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", $iStride, "int", $iPixelFormat, "ptr", $pScan0, "int*", 0)
 If @error Then Return SetError(@error, @extended, 0)
 Return $aResult[6]
EndFunc   ;==>_GDIPlus_BitmapCreateFromScan0

Regards,

taietel

Link to comment
Share on other sites

Awesome! No artifacts this time.:mellow:

Now I'm trying to make $iStretchW & $iStretchH be the final width & height, not adders. I figured out how to make everything stretch right, & now I am trying to figure out the layout.

ChrisN

Link to comment
Share on other sites

Hi all,

I just ran into a weird bug with this code. It seems that if the picture you are stretching small, and you stretch it to a large image, the stretched areas will fade to transparency!

My picture:

Posted Image

My code:

#include <GDIPlus.au3>

GUICreate("test", 300, 300)
_ImageStretchArray(@ScriptDir & "\tc.bmp", 200, 200, 4, @TempDir & "\temp.bmp")
GUICtrlCreateLabel("TESTING", 180, 160)
GUICtrlCreatePic(@TempDir & "\temp.bmp", 10, 10, 200, 200)
GUISetState()

While 1
 If GUIGetMsg() = -3 Then Exit
WEnd

 


; #FUNCTION# ====================================================================================================================
; Name ..........: _ImageStretchArray
; Description ...: Stretch a image (no. 1,3,4,5,7), but not the corners (no. 0,2,6,8)
;       |0 1 2|
;       |3 4 5|
;       |6 7 8|
; Syntax ........: _ImageStretchArray($sImage[, $iStretchW = 0[, $iStretchH = 0[, $iCorner = 0[, $sOutImg = ""]]]])
; Parameters ....: $sImage              - Path to the image.
;                  $iStretchW           - [optional] An integer value. Default is 0.
;                  $iStretchH           - [optional] An integer value. Default is 0.
;                  $iCorner             - [optional] An integer value. Default is 0.
;                  $sOutImg             - [optional] Path to the output image. Default is @ScriptDir&"\stretched.png".
; Return values .: Path to the stretched image
; Author ........: Mihai Iancu (aka taietel)
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func _ImageStretchArray($sImage, $iStretchW = 0, $iStretchH = 0, $iCorner = 0, $sOutImg = "")
 If $sOutImg = "" Then $sOutImg = @ScriptDir & "\stretched.png"
 Local $hImage, $aImages[9][5], $hTmpBmp[6], $hGraphic[6]
 Local $iW, $iH
 _GDIPlus_Startup()
 $hImage = _GDIPlus_ImageLoadFromFile($sImage)
 $iW = _GDIPlus_ImageGetWidth($hImage)
 $iH = _GDIPlus_ImageGetHeight($hImage)
 ;$iStretchH -= $iH
 ;$iStretchW -= $iW
 For $j = 0 To 8
  Switch $j;w
   Case 1, 4, 7
    $aImages[$j][3] = $iW - 2 * $iCorner
   Case Else
    $aImages[$j][3] = $iCorner
  EndSwitch
  Switch $j;h
   Case 0, 1, 2, 6, 7, 8
    $aImages[$j][4] = $iCorner
   Case Else
    $aImages[$j][4] = $iH - 2 * $iCorner
  EndSwitch
  Switch $j;x
   Case 2, 5, 8
    $aImages[$j][1] = $iW - $iCorner
   Case 1, 4, 7
    $aImages[$j][1] = $iCorner
   Case Else
    $aImages[$j][1] = 0
  EndSwitch
  Switch $j;y
   Case 0, 1, 2
    $aImages[$j][2] = 0
   Case 3, 4, 5
    $aImages[$j][2] = $iCorner
   Case Else
    $aImages[$j][2] = $iH - $iCorner
  EndSwitch
  $aImages[$j][0] = _GDIPlus_BitmapCloneArea($hImage, $aImages[$j][1], $aImages[$j][2], $aImages[$j][3], $aImages[$j][4], $GDIP_PXF32ARGB)
 Next

 ;create an empty bitmap, stretched
 $hTmpBmp[0] = _GDIPlus_BitmapCreateFromScan0($iW + $iStretchW, $iH + $iStretchH)
 ;$hTmpBmp[0] = _GDIPlus_BitmapCreateFromScan0($iStretchW, $iStretchH)
 $hGraphic[0] = _GDIPlus_ImageGetGraphicsContext($hTmpBmp[0])
 _GDIPlus_GraphicsClear($hGraphic[0], 0x00FFFFFF)
 _GDIPlus_GraphicsSetSmoothingMode($hGraphic[0], 2)

 ;and fill it with array of images
 ;first, draw those pieces that are unchanged
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[0][0], $aImages[0][1], $aImages[0][2])
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[6][0], $aImages[6][1], $aImages[0][4] + $aImages[3][4] + $iStretchH)
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[2][0], $aImages[0][3] + $aImages[1][3] + $iStretchW, $aImages[0][2])
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[8][0], $aImages[0][3] + $aImages[1][3] + $iStretchW, $aImages[0][4] + $aImages[3][4] + $iStretchH)
 ;then those that are stretched
 $hTmpBmp[1] = _GDIPlus_BitmapCreateFromScan0($iW + $iStretchW - 2 * $aImages[0][3], $aImages[0][4])
 ;$hTmpBmp[1] = _GDIPlus_BitmapCreateFromScan0($iStretchW-2*$aImages[0][3], $aImages[0][4])
 $hGraphic[1] = _GDIPlus_ImageGetGraphicsContext($hTmpBmp[1])
 _GDIPlus_GraphicsClear($hGraphic[1], 0x00FFFFFF)
 _GDIPlus_GraphicsDrawImageRect($hGraphic[1], $aImages[1][0], $aImages[0][1], $aImages[1][2], $iW + $iStretchW - 2 * $aImages[0][3] + 1, $aImages[0][4])
 ; _GDIPlus_GraphicsDrawImageRect($hGraphic[1], $aImages[1][0], $aImages[0][1], $aImages[1][2], $iStretchW-2*$aImages[0][3]+1, $aImages[0][4])
 $aImages[1][0] = $hTmpBmp[1]
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[1][0], $aImages[1][1], $aImages[0][2])

 $hTmpBmp[2] = _GDIPlus_BitmapCreateFromScan0($aImages[0][3], $iH + $iStretchH - 2 * $aImages[0][4])
 ;$hTmpBmp[2] = _GDIPlus_BitmapCreateFromScan0($aImages[0][3], $iStretchH-2*$aImages[0][4])
 $hGraphic[2] = _GDIPlus_ImageGetGraphicsContext($hTmpBmp[2])
 _GDIPlus_GraphicsClear($hGraphic[2], 0x00FFFFFF)
 _GDIPlus_GraphicsDrawImageRect($hGraphic[2], $aImages[3][0], $aImages[0][1], $aImages[1][2], $aImages[0][3], $iH + $iStretchH - 2 * $aImages[0][4] + 1)
 ;_GDIPlus_GraphicsDrawImageRect($hGraphic[2], $aImages[3][0], $aImages[0][1], $aImages[1][2], $aImages[0][3], $iStretchH-2*$aImages[0][4]+1)
 $aImages[3][0] = $hTmpBmp[2]
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[3][0], $aImages[0][1], $aImages[0][4])

 $hTmpBmp[3] = _GDIPlus_BitmapCreateFromScan0($iW + $iStretchW - 2 * $aImages[0][3], $iH + $iStretchH - 2 * $aImages[0][4])
 ;$hTmpBmp[3] = _GDIPlus_BitmapCreateFromScan0($iStretchW-2*$aImages[0][3], $iStretchH-2*$aImages[0][4])
 $hGraphic[3] = _GDIPlus_ImageGetGraphicsContext($hTmpBmp[3])
 _GDIPlus_GraphicsClear($hGraphic[3], 0x00FFFFFF)
 _GDIPlus_GraphicsDrawImageRect($hGraphic[3], $aImages[4][0], $aImages[0][1], $aImages[1][2], $iW + $iStretchW - 2 * $aImages[0][3] + 1, $iH + $iStretchH - 2 * $aImages[0][4] + 1)
 ;_GDIPlus_GraphicsDrawImageRect($hGraphic[3], $aImages[4][0], $aImages[0][1], $aImages[1][2], $iStretchW-2*$aImages[0][3]+1,$iStretchH-2*$aImages[0][4]+1)
 $aImages[4][0] = $hTmpBmp[3]
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[4][0], $aImages[0][3], $aImages[0][4])

 $hTmpBmp[4] = _GDIPlus_BitmapCreateFromScan0($aImages[0][3], $iH + $iStretchH - 2 * $aImages[0][4])
 ; $hTmpBmp[4] = _GDIPlus_BitmapCreateFromScan0($aImages[0][3], $iStretchH-2*$aImages[0][4])
 $hGraphic[4] = _GDIPlus_ImageGetGraphicsContext($hTmpBmp[4])
 _GDIPlus_GraphicsClear($hGraphic[4], 0x00FFFFFF)
 _GDIPlus_GraphicsDrawImageRect($hGraphic[4], $aImages[5][0], $aImages[0][1], $aImages[1][2], $aImages[0][3], $iH + $iStretchH - 2 * $aImages[0][4] + 1)
 ; _GDIPlus_GraphicsDrawImageRect($hGraphic[4], $aImages[5][0], $aImages[0][1], $aImages[1][2], $aImages[0][3], $iStretchH-2*$aImages[0][4]+1)
 $aImages[5][0] = $hTmpBmp[4]
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[5][0], $aImages[0][3] + $aImages[1][3] + $iStretchW, $aImages[0][4])

 $hTmpBmp[5] = _GDIPlus_BitmapCreateFromScan0($iW + $iStretchW - 2 * $aImages[0][3], $aImages[0][4])
 ;$hTmpBmp[5] = _GDIPlus_BitmapCreateFromScan0($iStretchW-2*$aImages[0][3], $aImages[0][4])
 $hGraphic[5] = _GDIPlus_ImageGetGraphicsContext($hTmpBmp[5])
 _GDIPlus_GraphicsClear($hGraphic[5], 0x00FFFFFF)
 _GDIPlus_GraphicsDrawImageRect($hGraphic[5], $aImages[7][0], $aImages[0][1], $aImages[1][2], $iW + $iStretchW - 2 * $aImages[0][3] + 1, $aImages[0][4])
 ; _GDIPlus_GraphicsDrawImageRect($hGraphic[5], $aImages[7][0], $aImages[0][1], $aImages[1][2], $iStretchW-2*$aImages[0][3]+1, $aImages[0][4])
 $aImages[7][0] = $hTmpBmp[5]
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[7][0], $aImages[0][3], $aImages[0][4] + $aImages[4][4] + $iStretchH)

 ;save the file
 _GDIPlus_ImageSaveToFile($hTmpBmp[0], $sOutImg)
 ;clean up
 For $i = 0 To 8
  _GDIPlus_ImageDispose($aImages[$i][0])
 Next
 For $i = 0 To 5
  _GDIPlus_ImageDispose($hTmpBmp[$i])
  _GDIPlus_GraphicsDispose($hGraphic[$i])
 Next

 _GDIPlus_ImageDispose($hImage)
 _GDIPlus_Shutdown()
 Return $sOutImg
EndFunc   ;==>_ImageStretchArray

Func _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $iStride = 0, $iPixelFormat = 0x0026200A, $pScan0 = 0)
 ;Thanks to Authenticity
 Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", $iStride, "int", $iPixelFormat, "ptr", $pScan0, "int*", 0)
 If @error Then Return SetError(@error, @extended, 0)
 Return $aResult[6]
EndFunc   ;==>_GDIPlus_BitmapCreateFromScan0

My result:

Posted Image

I didn't know that AutoIt's picture control supported transparency! :mellow:

ChrisN

Link to comment
Share on other sites

This not a bug, it is a feature.

If you replace the color value of all _GDIPlus_GraphicsClear() lines from 0x00FFFFFF to 0xFF000000 it will disable the alpha channel and thus no transparency will occure.

Nice code taietel :mellow:

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Here another way (fast hack):

#include <GDIPlus.au3>
_GDIPlus_Startup()

;1st example with the image from post #12
$hImage = _GDIPlus_ImageLoadFromFile("0c535.png")
$hBmp1 = StretchImage($hImage, 20, 0, 80, 100, 1.5, 1); stretch width
$hBmp2 = StretchImage($hBmp1, 0, 20, 130, 80, 1, 1.5) ;stretch height
$output = @ScriptDir & "\Result.png"
_GDIPlus_ImageSaveToFile($hBmp2, $output)
ShellExecute($output)
_GDIPlus_BitmapDispose($hBmp1)
_GDIPlus_BitmapDispose($hBmp2)
_GDIPlus_ImageDispose($hImage)

;2nd example with the blue image from post #15
$hImage = _GDIPlus_ImageLoadFromFile("s1cj9.png")
$hBmp1 = StretchImage($hImage, 3, 0, 14, 33, 5, 1)
$output = @ScriptDir & "\Result2.png"
_GDIPlus_ImageSaveToFile($hBmp1, $output)
ShellExecute($output)
_GDIPlus_BitmapDispose($hBmp1)
_GDIPlus_ImageDispose($hImage)

_GDIPlus_Shutdown()
Exit

; #FUNCTION# ======================================================================================
; Name ............:        StretchImage()
; Description ...:      Stretches an image at the coordinates x1, y1, x2, y2 with the scale factor x and scale factor y
; Syntax ..........:        StretchImage($hImage, $x1, $y1, $x2, $y2, $scalex, $scaley[, $quality = 5])
; Parameters ....:      $hImage  - handle of the image object
;                               $x1      - x1 coordinate
;                               $y1      - y1 coordinate
;                               $x2      - x2 coordinate
;                               $y2      - y2 coordinate
;                               $scalex  - factor how to scale the width of the selected area. 1 means no scale
;                               $scaley  - factor how to scale the height of the selected area. 1 means no scale
;                               $quality - [optional] - default=5:
;                                           0 - Default interpolation mode
;                                           1 - Low-quality mode
;                                           2 - High-quality mode
;                                           3 - Bilinear interpolation. No prefiltering is done
;                                           4 - Bicubic interpolation. No prefiltering is done
;                                           5 - Nearest-neighbor interpolation
;                                           6 - High-quality, bilinear interpolation. Prefiltering is performed to ensure high-quality shrinking
;                                           7 - High-quality, bicubic interpolation. Prefiltering is performed to ensure high-quality shrinking
; Return values .:  Success:    handle to a new created bitmap (don't forget to dispose bitmap otherwise memory leak will occure!)
;                               Failure:    error code:
;                                           1 - GDI+ not initialized
;                                           2 - $hImage is an invalid image handle
;                                           3 - $x1 >= $x2 or $y1 >= $y2 is given which makes no sense
;                                           4 - quality value is out of range
;                                           5 - unable to create bitmap
; Author ..........:        UEZ
; Version .........:        v0.50 build 2011-08-11 beta
; Modified ........:
; Remarks ........:         GDIPlus.au3 is needed and
; Related ..........:   GDI+
; Example ........:         Yes:
;                               #include <GDIPlus.au3>
;                               _GDIPlus_Startup()
;                               $hImage = _GDIPlus_ImageLoadFromFile("Stretch_Me.png")
;                               $hBmp1 = StretchImage($hImage, 20, 0, 80, 100, 1.5, 1); stretch width
;                               $output = @ScriptDir & "\Result.png"
;                               _GDIPlus_ImageSaveToFile($hBmp1, $output)
;                               ShellExecute($output)
;                               _GDIPlus_BitmapDispose($hBmp1)
;                               _GDIPlus_ImageDispose($hImage)
;                               _GDIPlus_Shutdown()
;                               Exit
; =================================================================================================
Func StretchImage($hImage, $x1, $y1, $x2, $y2, $scalex, $scaley, $quality = 5)
    If Not $ghGDIPDll Then Return SetError(1, 0, 0)
    If _GDIPlus_ImageGetType($hImage) = -1 Then Return SetError(2, 0, 0)
    If $x1 >= $x2 Or $y1 >= $y2 Then Return SetError(3, 0, 0)
    If $quality < 0 Or $quality > 7 Then Return SetError(4, 0, 0)
    Local $iW = _GDIPlus_ImageGetWidth($hImage)
    Local $iH = _GDIPlus_ImageGetHeight($hImage)
    Local $new_w = ($x2 - $x1) * $scalex + $iW - ($x2 - $x1)
    Local $new_h = ($y2 - $y1) * $scaley + $iH - ($y2 - $y1)
    Local $aResult =  DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $new_w, "int", $new_h, "int", 0, "int", 0x0026200A, "ptr", 0, "int*", 0)
    If @error Then Return SetError(5, 0, 0)
    Local $hBitmap = $aResult[6]
    Local $hContext = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    DllCall($ghGDIPDll, "uint", "GdipSetInterpolationMode", "handle", $hContext, "int", $quality)
    _GDIPlus_GraphicsDrawImageRectRect($hContext, $hImage, $x1, $y1, ($x2 - $x1), ($y2 - $y1), $x1, $y1, ($x2 - $x1) * $scalex, ($y2 - $y1) * $scaley)
    If $x1 Then
        _GDIPlus_GraphicsDrawImageRectRect($hContext, $hImage, 0, 0, $x1, $iH, 0, 0, $x1, $iH * $scaley)
        _GDIPlus_GraphicsDrawImageRectRect($hContext, $hImage, $x2, 0, $iW - $x2, $iH, $x1 + ($x2 - $x1) * $scalex, 0, $iW - $x2, $iH * $scaley)
    Else
        _GDIPlus_GraphicsDrawImageRectRect($hContext, $hImage, 0, 0, $iW, $y1, 0, 0, $iW, $y1)
        _GDIPlus_GraphicsDrawImageRectRect($hContext, $hImage, 0, $y2, $iW, $iH - $y2, 0, $y1 + ($y2 - $y1) * $scaley, $iW, $iH - $y2)
    EndIf
    _GDIPlus_GraphicsDispose($hContext)
    Return $hBitmap
EndFunc

Example is made for original image from post

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Another script to chew on. Thanks UEZ! :mellow:

One question, regarding my script: Why the stretched part is fading to the right? I like the "fading effect", but I don't understand it.:)

[EDIT] typo

Edited by taietel
Link to comment
Share on other sites

Probably it is the result when you draw the image with _GDIPlus_GraphicsDrawImageRect() which causes the "fading effect".

When you save each of 5 images during the creation you will see that each of them have already the fading effect.

; #FUNCTION# ====================================================================================================================
; Name ..........: _ImageStretchArray
; Description ...: Stretch a image (no. 1,3,4,5,7), but not the corners (no. 0,2,6,8)
;       |0 1 2|
;       |3 4 5|
;       |6 7 8|
; Syntax ........: _ImageStretchArray($sImage[, $iStretchW = 0[, $iStretchH = 0[, $iCorner = 0[, $sOutImg = ""]]]])
; Parameters ....: $sImage              - Path to the image.
;                  $iStretchW           - [optional] An integer value. Default is 0.
;                  $iStretchH           - [optional] An integer value. Default is 0.
;                  $iCorner             - [optional] An integer value. Default is 0.
;                  $sOutImg             - [optional] Path to the output image. Default is @ScriptDir&"\stretched.png".
; Return values .: Path to the stretched image
; Author ........: Mihai Iancu (aka taietel)
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func _ImageStretchArray($sImage, $iStretchW = 0, $iStretchH = 0, $iCorner = 0, $sOutImg = "")
 If $sOutImg = "" Then $sOutImg = @ScriptDir & "\stretched.png"
 Local $hImage, $aImages[9][5], $hTmpBmp[6], $hGraphic[6]
 Local $iW, $iH, $clr = 0x00FFFFFF
 _GDIPlus_Startup()
 $hImage = _GDIPlus_ImageLoadFromFile($sImage)
 $iW = _GDIPlus_ImageGetWidth($hImage)
 $iH = _GDIPlus_ImageGetHeight($hImage)
 ;$iStretchH -= $iH
 ;$iStretchW -= $iW
 For $j = 0 To 8
  Switch $j;w
   Case 1, 4, 7
    $aImages[$j][3] = $iW - 2 * $iCorner
   Case Else
    $aImages[$j][3] = $iCorner
  EndSwitch
  Switch $j;h
   Case 0, 1, 2, 6, 7, 8
    $aImages[$j][4] = $iCorner
   Case Else
    $aImages[$j][4] = $iH - 2 * $iCorner
  EndSwitch
  Switch $j;x
   Case 2, 5, 8
    $aImages[$j][1] = $iW - $iCorner
   Case 1, 4, 7
    $aImages[$j][1] = $iCorner
   Case Else
    $aImages[$j][1] = 0
  EndSwitch
  Switch $j;y
   Case 0, 1, 2
    $aImages[$j][2] = 0
   Case 3, 4, 5
    $aImages[$j][2] = $iCorner
   Case Else
    $aImages[$j][2] = $iH - $iCorner
  EndSwitch
  $aImages[$j][0] = _GDIPlus_BitmapCloneArea($hImage, $aImages[$j][1], $aImages[$j][2], $aImages[$j][3], $aImages[$j][4], $GDIP_PXF32ARGB)
 Next

 ;create an empty bitmap, stretched
 $hTmpBmp[0] = _GDIPlus_BitmapCreateFromScan0($iW + $iStretchW, $iH + $iStretchH)
 ;$hTmpBmp[0] = _GDIPlus_BitmapCreateFromScan0($iStretchW, $iStretchH)
 $hGraphic[0] = _GDIPlus_ImageGetGraphicsContext($hTmpBmp[0])
 _GDIPlus_GraphicsClear($hGraphic[0], $clr)
 _GDIPlus_GraphicsSetSmoothingMode($hGraphic[0], 2)

 ;and fill it with array of images
 ;first, draw those pieces that are unchanged
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[0][0], $aImages[0][1], $aImages[0][2])
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[6][0], $aImages[6][1], $aImages[0][4] + $aImages[3][4] + $iStretchH)
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[2][0], $aImages[0][3] + $aImages[1][3] + $iStretchW, $aImages[0][2])
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[8][0], $aImages[0][3] + $aImages[1][3] + $iStretchW, $aImages[0][4] + $aImages[3][4] + $iStretchH)

 ;then those that are stretched
 $hTmpBmp[1] = _GDIPlus_BitmapCreateFromScan0($iW + $iStretchW - 2 * $aImages[0][3], $aImages[0][4])
 ;$hTmpBmp[1] = _GDIPlus_BitmapCreateFromScan0($iStretchW-2*$aImages[0][3], $aImages[0][4])
 $hGraphic[1] = _GDIPlus_ImageGetGraphicsContext($hTmpBmp[1])
 _GDIPlus_GraphicsClear($hGraphic[1], $clr)
 _GDIPlus_GraphicsDrawImageRect($hGraphic[1], $aImages[1][0], $aImages[0][1], $aImages[1][2], $iW + $iStretchW - 2 * $aImages[0][3] + 1, $aImages[0][4])
 ; _GDIPlus_GraphicsDrawImageRect($hGraphic[1], $aImages[1][0], $aImages[0][1], $aImages[1][2], $iStretchW-2*$aImages[0][3]+1, $aImages[0][4])
 _GDIPlus_ImageSaveToFile($hTmpBmp[1], "1.png")
 $aImages[1][0] = $hTmpBmp[1]
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[1][0], $aImages[1][1], $aImages[0][2])

 $hTmpBmp[2] = _GDIPlus_BitmapCreateFromScan0($aImages[0][3], $iH + $iStretchH - 2 * $aImages[0][4])
 ;$hTmpBmp[2] = _GDIPlus_BitmapCreateFromScan0($aImages[0][3], $iStretchH-2*$aImages[0][4])
 $hGraphic[2] = _GDIPlus_ImageGetGraphicsContext($hTmpBmp[2])
 _GDIPlus_GraphicsClear($hGraphic[2], $clr)
 _GDIPlus_GraphicsDrawImageRect($hGraphic[2], $aImages[3][0], $aImages[0][1], $aImages[1][2], $aImages[0][3], $iH + $iStretchH - 2 * $aImages[0][4] + 1)
 ;_GDIPlus_GraphicsDrawImageRect($hGraphic[2], $aImages[3][0], $aImages[0][1], $aImages[1][2], $aImages[0][3], $iStretchH-2*$aImages[0][4]+1)
 _GDIPlus_ImageSaveToFile($hTmpBmp[2], "2.png")

 $aImages[3][0] = $hTmpBmp[2]
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[3][0], $aImages[0][1], $aImages[0][4])

 $hTmpBmp[3] = _GDIPlus_BitmapCreateFromScan0($iW + $iStretchW - 2 * $aImages[0][3], $iH + $iStretchH - 2 * $aImages[0][4])
 ;$hTmpBmp[3] = _GDIPlus_BitmapCreateFromScan0($iStretchW-2*$aImages[0][3], $iStretchH-2*$aImages[0][4])
 $hGraphic[3] = _GDIPlus_ImageGetGraphicsContext($hTmpBmp[3])
 _GDIPlus_GraphicsClear($hGraphic[3], $clr)
 _GDIPlus_GraphicsDrawImageRect($hGraphic[3], $aImages[4][0], $aImages[0][1], $aImages[1][2], $iW + $iStretchW - 2 * $aImages[0][3] + 1, $iH + $iStretchH - 2 * $aImages[0][4] + 1)
 ;_GDIPlus_GraphicsDrawImageRect($hGraphic[3], $aImages[4][0], $aImages[0][1], $aImages[1][2], $iStretchW-2*$aImages[0][3]+1,$iStretchH-2*$aImages[0][4]+1)
 _GDIPlus_ImageSaveToFile($hTmpBmp[3], "3.png")

 $aImages[4][0] = $hTmpBmp[3]
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[4][0], $aImages[0][3], $aImages[0][4])

 $hTmpBmp[4] = _GDIPlus_BitmapCreateFromScan0($aImages[0][3], $iH + $iStretchH - 2 * $aImages[0][4])
 ; $hTmpBmp[4] = _GDIPlus_BitmapCreateFromScan0($aImages[0][3], $iStretchH-2*$aImages[0][4])
 $hGraphic[4] = _GDIPlus_ImageGetGraphicsContext($hTmpBmp[4])
 _GDIPlus_GraphicsClear($hGraphic[4], $clr)
 _GDIPlus_GraphicsDrawImageRect($hGraphic[4], $aImages[5][0], $aImages[0][1], $aImages[1][2], $aImages[0][3], $iH + $iStretchH - 2 * $aImages[0][4] + 1)
 ; _GDIPlus_GraphicsDrawImageRect($hGraphic[4], $aImages[5][0], $aImages[0][1], $aImages[1][2], $aImages[0][3], $iStretchH-2*$aImages[0][4]+1)
 _GDIPlus_ImageSaveToFile($hTmpBmp[4], "4.png")

 $aImages[5][0] = $hTmpBmp[4]
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[5][0], $aImages[0][3] + $aImages[1][3] + $iStretchW, $aImages[0][4])

 $hTmpBmp[5] = _GDIPlus_BitmapCreateFromScan0($iW + $iStretchW - 2 * $aImages[0][3], $aImages[0][4])
 ;$hTmpBmp[5] = _GDIPlus_BitmapCreateFromScan0($iStretchW-2*$aImages[0][3], $aImages[0][4])
 $hGraphic[5] = _GDIPlus_ImageGetGraphicsContext($hTmpBmp[5])
 _GDIPlus_GraphicsClear($hGraphic[5], $clr)
 _GDIPlus_GraphicsDrawImageRect($hGraphic[5], $aImages[7][0], $aImages[0][1], $aImages[1][2], $iW + $iStretchW - 2 * $aImages[0][3] + 1, $aImages[0][4])
 ; _GDIPlus_GraphicsDrawImageRect($hGraphic[5], $aImages[7][0], $aImages[0][1], $aImages[1][2], $iStretchW-2*$aImages[0][3]+1, $aImages[0][4])
 _GDIPlus_ImageSaveToFile($hTmpBmp[5], "5.png")

 $aImages[7][0] = $hTmpBmp[5]
 _GDIPlus_GraphicsDrawImage($hGraphic[0], $aImages[7][0], $aImages[0][3], $aImages[0][4] + $aImages[4][4] + $iStretchH)

 ;save the file
 _GDIPlus_ImageSaveToFile($hTmpBmp[0], $sOutImg)
 ;clean up
 For $i = 0 To 8
  _GDIPlus_ImageDispose($aImages[$i][0])
 Next
 For $i = 0 To 5
  _GDIPlus_ImageDispose($hTmpBmp[$i])
  _GDIPlus_GraphicsDispose($hGraphic[$i])
 Next

 _GDIPlus_ImageDispose($hImage)
 _GDIPlus_Shutdown()
 Return $sOutImg
EndFunc   ;==>_ImageStretchArray

Br,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...