Thursday, April 18, 2013

Ֆայլեր։ Pixmap պատկերի խոշորացում

Ենթադրենք տրված է pixmap պատկեր պարունակող պարզեցված ֆայլ և պահանջվում է գրել մի ծրագիր, որը պատկերը կխոշորացնի տրված գործակցով։ Օրինակ, ստորև բերված են հայերեն "Բ" տառի սկզբնական pixmap պատկերը և նրա երկու անգամ խոշորտացված տարբերակը։
......
..##..
.#..#.
.#..#.
.#....
.####.
.#....
.#....
.#....
......
                 
............
............
....####....
....####....
..##....##..
..##....##..
..##....##..
..##....##..
..##........
..##........
..########..
..########..
..##........
..##........
..##........
..##........
..##........
..##........
............
............
Ծրագիրը պետք կարդա ձախ կողմի պատկերը պարունակող ֆայլը և ստեղծի նոր ֆայլ՝ աջ պատկերի պարունակմամբ։

Թող ամբողջ աշխատանքը կատարող պրոցեդուրան կոչվի enlarge, որը ստանում է երկու արգումենտ. պատկերը պարունակող ֆայլի անունը՝ pixmap և խոշորացման գործակիցը՝ sc։
proc enlarge { pixmap {sc 2} } {
Հետո պետք է բացել ֆայլը, նրա պարունակությունը կարդալ որևէ փոփոխականի մեջ, ապա նորից փակել ֆայլը։ Tcl լեզվում ֆայը բացվում է open պրոցեդուրայով, որի առաջին արգումենտը ֆալի անունն է, իսկ երկրորդով որոշվում է, թե ինչ գործողություն է կատարվելու ֆայլի հետ՝ գրել (w), կարդալ (r) և այլն։ open պրոցեդուրան վերադարձնում է ֆայլային հոսք, որից կարելի է կարդալ, կամ նրա մեջ կարելի է գրել։
  set inp [open $pixmap r]
Ֆայլի պարունակությունը ամբողջությամբ կարդում է read պրոցեդուրան։ Այն ստանում է կարդալու համար բացված ֆայլային հոսք և վերադարձնում է հոսքի ամբողջ պարունակությունը։
  set img [read $inp]
Դե, իսկ close պրոցեդուրան փակում է բացված ֆայլային հոսքը։
  close $inp
Պատկերը \(n\) անգամ խոշորացնելու համար պետք է նրա ամեն մի կետը հորիզոնական և ուղղահայաց ուղղություններով ընդարձակել \(n\) անգամ։ Դրա համար պետք է վերցնել սկզբնական պատկերի ամեն մի տողը և, \(n\) անգամ կրկնելով նրա ամեն մի սիմվոլը, ստանալ նոր տող։ ՈՒղղահայաց ընդարձակման համար պետք է \(n\) անգամ կրկնել կառուցված տողը։

Արդյունքը կուտակելու համար նախատեսենք result փոփոխականը որպես դատարկ ցուցակ։
  set result [list]
Քանի որ տրված ֆայլի ամբողջ պարունակությունը կարդացվել էր img փոփոխականի մեջ, պետք է այն split պրոցեդուրայով տրոհել տողերի ու իտերացիա կազմակերպել տողերով։ split պրոցեդուրայի երկրորդ արգումենտով տրվում է այն բաժանիչը, ըստ որի պետք է տողը տրոհել ցուցակի։
  foreach line [split $img \n] {
Տողի սիմվոլներով իտերացիայի համար այն կարող ենք սիմվոլների ցուցակի վերածել split պրոցեդուրայով և ցուցակով անցնել foreach պրոցեդուրայով։ Հերթական սիմվոլը դիտարկելիս string repeat հրամանով այն պետք է բազմապատկել պահանջված քանակով ու կցել կառուցվող տողին՝ str փոփոխականին: Իսկ բոլոր սիմվոլներով անցնելուց հետո կառուցված տողին կցենք նոր տողի սիմվոլը։
    set str {}
    foreach char [split $line {}] {
      append str [string repeat $char $sc]
    }
    append str \n
Կառուցված տողը բազմապատկելու համար նորից օգտագործենք string repeat հրաման հրամանը և result ցուցակին կցենք lappend պրոցեդուրայով։
    lappend result [string repeat $str $sc]
  }
Այս դրությամբ արդեն result փոփոխականը պարունակում է նախնական պատկերի խոշորացված տարբերակը։ open հրամանով բացենք ֆայլ գրելու համար։
  set out [open sc$sc$pixmap w]
Այդ ֆայլի մեջ արտածենք կառուցված տողերի ցուցակը՝ դրանք նախապես իրար կցելով join պրոցեդուրայով։
  puts $out [join $result {}]
ՈՒ փակենք ֆայլը։
  close $out
}
Վերջ։ Հիմա կարող ենք կանչել enlarge պրոցեդուրան՝ նրան տալով pixmap ֆայլը և խոշորացման գործակիցը։


Ամբողջական պրոցեդուրան։
proc enlarge { pixmap {sc 2} } {
  set inp [open $pixmap r]
  set img [read $inp]
  close $inp

  set result [list]
  foreach line [split $img \n] {
    set str {}
    foreach char [split $line {}] {
      append str [string repeat $char $sc]
    }
    append str \n
    lappend result [string repeat $str $sc]
  }

  set out [open sc$sc$pixmap w]
  puts $out [join $result {}]
  close $out
}

No comments:

Post a Comment